* [PATCH v3 01/35] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
@ 2019-07-04 14:41 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 02/35] OvmfPkg: Create platform OvmfXen Anthony PERARD
` (36 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:41 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Add missing dependency on PciLib
and remove extra includes of OvmfPlatforms.h.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v2:
- also add PciLib.h include to the .c
- and remove extra include of OvmfPlatforms.h
OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf | 1 +
OvmfPkg/Library/ResetSystemLib/ResetSystemLib.c | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
index 7c44f99a5c..2f24dac87f 100644
--- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
+++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -30,4 +30,5 @@ [Packages]
[LibraryClasses]
DebugLib
IoLib
+ PciLib
TimerLib
diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.c b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.c
index 27460cd100..98dd80e33c 100644
--- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.c
+++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -11,11 +11,10 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
+#include <Library/PciLib.h>
#include <Library/TimerLib.h>
#include <OvmfPlatforms.h>
-#include <OvmfPlatforms.h>
-
VOID
AcpiPmControl (
UINTN SuspendType
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 02/35] OvmfPkg: Create platform OvmfXen
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
2019-07-04 14:41 ` [PATCH v3 01/35] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 13:29 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 03/35] OvmfPkg: Introduce XenResetVector Anthony PERARD
` (35 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
OvmfXen is a copy of OvmfX64, removing VirtIO and some SMM.
This new platform will be changed to make it works on two types of Xen
guest: HVM and PVH.
Compare to OvmfX64, this patch:
- changed: PLATFORM_GUID, OUTPUT_DIRECTORY, FLASH_DEFINITION
- removed: VirtioLib class resolution
- removed: all UEFI_DRIVER modules for virtio devices
- removed: DXE_SMM_DRIVER and SMM_CORE lib class resolutions
- removed: DXE_SMM_DRIVER and SMM_CORE FDF rules
- removed: Everything related to SMM_REQUIRE==true
- removed: Everything related to SECURE_BOOT_ENABLE==true
- removed: Everything related to TPM2_ENABLE==true
- changed: PcdPciDisableBusEnumeration dynamic default flipped to TRUE
- changed: default FD_SIZE_IN_KB to 2M.
- reverted d272449d9e1e, "OvmfPkg: raise DXEFV size to 11 MB"
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- rebased, SPDX + 8259/8254 changes
OvmfPkg/OvmfXen.dsc | 729 ++++++++++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfXen.fdf | 439 ++++++++++++++++++++++++++
2 files changed, 1168 insertions(+)
create mode 100644 OvmfPkg/OvmfXen.dsc
create mode 100644 OvmfPkg/OvmfXen.fdf
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
new file mode 100644
index 0000000000..3b56815dd7
--- /dev/null
+++ b/OvmfPkg/OvmfXen.dsc
@@ -0,0 +1,729 @@
+## @file
+# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
+#
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = Ovmf
+ PLATFORM_GUID = e3aa4fbe-9459-482d-bd40-d3f3b5f89d6e
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/OvmfXen
+ SUPPORTED_ARCHITECTURES = X64
+ BUILD_TARGETS = NOOPT|DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = OvmfPkg/OvmfXen.fdf
+
+ #
+ # Defines for default states. These can be changed on the command line.
+ # -D FLAG=VALUE
+ #
+
+ #
+ # Network definition
+ #
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
+
+!include NetworkPkg/NetworkDefines.dsc.inc
+
+ #
+ # Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to
+ # one of the supported values, in place of any of the convenience macros, is
+ # permitted.
+ #
+!ifdef $(FD_SIZE_1MB)
+ DEFINE FD_SIZE_IN_KB = 1024
+!else
+!ifdef $(FD_SIZE_2MB)
+ DEFINE FD_SIZE_IN_KB = 2048
+!else
+!ifdef $(FD_SIZE_4MB)
+ DEFINE FD_SIZE_IN_KB = 4096
+!else
+ DEFINE FD_SIZE_IN_KB = 2048
+!endif
+!endif
+!endif
+
+[BuildOptions]
+ GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+ INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+ MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
+!if $(TOOL_CHAIN_TAG) != "XCODE5"
+ GCC:*_*_*_CC_FLAGS = -mno-mmx -mno-sse
+!endif
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ MSFT:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+ GCC:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+ INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+!endif
+
+ #
+ # Disable deprecated APIs.
+ #
+ MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+ INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+ GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+ GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+ XCODE:*_*_*_DLINK_FLAGS =
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+ GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+ XCODE:*_*_*_DLINK_FLAGS =
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+ 0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+ PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+ PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
+ PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
+ PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+ NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+ SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
+ LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+ MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+ DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
+ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+!if $(NETWORK_TLS_ENABLE) == TRUE
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!else
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+!endif
+
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+
+ #
+ # Network libraries
+ #
+!include NetworkPkg/NetworkLibs.dsc.inc
+
+!if $(NETWORK_TLS_ENABLE) == TRUE
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
+!endif
+
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+ XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+
+ Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
+
+[LibraryClasses.common]
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+
+[LibraryClasses.common.SEC]
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf
+!endif
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+ QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+ QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFixedAtBuild]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+!if $(NETWORK_TLS_ENABLE) == FALSE
+ # match PcdFlashNvStorageVariableSize purely for convenience
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
+!endif
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400
+!if $(NETWORK_TLS_ENABLE) == FALSE
+ # match PcdFlashNvStorageVariableSize purely for convenience
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000
+!endif
+!endif
+!if $(NETWORK_TLS_ENABLE) == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000
+!endif
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+ # DEBUG_INIT 0x00000001 // Initialization
+ # DEBUG_WARN 0x00000002 // Warnings
+ # DEBUG_LOAD 0x00000004 // Load events
+ # DEBUG_FS 0x00000008 // EFI File system
+ # DEBUG_POOL 0x00000010 // Alloc & Free (pool)
+ # DEBUG_PAGE 0x00000020 // Alloc & Free (page)
+ # DEBUG_INFO 0x00000040 // Informational debug messages
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers
+ # DEBUG_VARIABLE 0x00000100 // Variable
+ # DEBUG_BM 0x00000400 // Boot Manager
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver
+ # DEBUG_NET 0x00004000 // SNP Driver
+ # DEBUG_UNDI 0x00010000 // UNDI Driver
+ # DEBUG_LOADFILE 0x00020000 // LoadFile
+ # DEBUG_EVENT 0x00080000 // Event messages
+ # DEBUG_GCD 0x00100000 // Global Coherency Database changes
+ # DEBUG_CACHE 0x00200000 // Memory range cachability changes
+ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may
+ # // significantly impact boot performance
+ # DEBUG_ERROR 0x80000000 // Error
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+!endif
+
+ # This PCD is used to set the base address of the PCI express hierarchy. It
+ # is only consulted when OVMF runs on Q35. In that case it is programmed into
+ # the PCIEXBAR register.
+ #
+ # On Q35 machine types that QEMU intends to support in the long term, QEMU
+ # never lets the RAM below 4 GB exceed 2816 MB.
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xB0000000
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+ #
+ # Network Pcds
+ #
+!include NetworkPkg/NetworkPcds.dsc.inc
+
+ # IRQs 5, 9, 10, 11 are level-triggered
+ gUefiOvmfPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+
+ # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
+
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
+
+ # Set video resolution for text setup.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+
+ # Noexec settings for DXE.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
+
+ # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
+
+ # Set memory encryption mask
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+
+ gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+ OvmfPkg/ResetVector/ResetVector.inf
+
+ #
+ # SEC Phase modules
+ #
+ OvmfPkg/Sec/SecMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+
+ #
+ # PEI Phase modules
+ #
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+ OvmfPkg/PlatformPei/PlatformPei.inf
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+ UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+ #
+ # DXE Phase modules
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ }
+
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+ OvmfPkg/8259InterruptControllerDxe/8259.inf
+ UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+ UefiCpuPkg/CpuDxe/CpuDxe.inf
+ OvmfPkg/8254TimerDxe/8254Timer.inf
+ OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+ OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+ <LibraryClasses>
+ PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+ NULL|OvmfPkg/Library/PlatformHasIoMmuLib/PlatformHasIoMmuLib.inf
+ }
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
+ MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ MdeModulePkg/Universal/Metronome/Metronome.inf
+ PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+ MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
+ <LibraryClasses>
+!ifdef $(CSM_ENABLE)
+ NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
+ NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf
+!endif
+ }
+ MdeModulePkg/Logo/LogoDxe.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+!ifdef $(CSM_ENABLE)
+ NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf
+ NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
+!endif
+ }
+ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+ OvmfPkg/XenBusDxe/XenBusDxe.inf
+ OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+ <LibraryClasses>
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ FatPkg/EnhancedFatDxe/Fat.inf
+ MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+ OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+ OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+ OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+
+ #
+ # ISA Support
+ #
+ OvmfPkg/SioBusDxe/SioBusDxe.inf
+ MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+ #
+ # SMBIOS Support
+ #
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+ <LibraryClasses>
+ NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+ }
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ OvmfPkg/AcpiTables/AcpiTables.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+ MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+ #
+ # Network Support
+ #
+!include NetworkPkg/NetworkComponents.dsc.inc
+
+!if $(NETWORK_TLS_ENABLE) == TRUE
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
+ <LibraryClasses>
+ NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
+ }
+!endif
+
+ #
+ # Usb Support
+ #
+ MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+ MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+ OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
+ OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+ OvmfPkg/Csm/Csm16/Csm16.inf
+!endif
+
+!if $(TOOL_CHAIN_TAG) != "XCODE5"
+ ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
+!endif
+ ShellPkg/Application/Shell/Shell.inf {
+ <LibraryClasses>
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+!endif
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+ <PcdsFixedAtBuild>
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+ }
+
+ OvmfPkg/PlatformDxe/Platform.inf
+ OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+ OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+
+ #
+ # Variable driver stack (non-SMM)
+ #
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+ OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
+ <LibraryClasses>
+ PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
+ }
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ }
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
new file mode 100644
index 0000000000..f59647fd14
--- /dev/null
+++ b/OvmfPkg/OvmfXen.fdf
@@ -0,0 +1,439 @@
+## @file
+# Open Virtual Machine Firmware: FDF
+#
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+
+[Defines]
+!include OvmfPkg.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.OVMF]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(FW_BLOCKS)
+
+!include VarStore.fdf.inc
+
+$(VARS_SIZE)|$(FVMAIN_SIZE)
+FV = FVMAIN_COMPACT
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+FV = SECFV
+
+#
+# Build the variable store and the firmware code as separate flash device
+# images.
+#
+[FD.OVMF_VARS]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = $(VARS_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(VARS_BLOCKS)
+
+!include VarStore.fdf.inc
+
+[FD.OVMF_CODE]
+BaseAddress = $(CODE_BASE_ADDRESS)
+Size = $(CODE_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(CODE_BLOCKS)
+
+0x00000000|$(FVMAIN_SIZE)
+FV = FVMAIN_COMPACT
+
+$(FVMAIN_SIZE)|$(SECFV_SIZE)
+FV = SECFV
+
+################################################################################
+
+[FD.MEMFD]
+BaseAddress = $(MEMFD_BASE_ADDRESS)
+Size = 0xB00000
+ErasePolarity = 1
+BlockSize = 0x10000
+NumBlocks = 0xB0
+
+0x000000|0x006000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x010000|0x010000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+0x020000|0x0E0000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+FV = PEIFV
+
+0x100000|0xA00000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+FV = DXEFV
+
+################################################################################
+
+[FV.SECFV]
+FvNameGuid = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
+BlockSize = 0x1000
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF OvmfPkg/Sec/SecMain.inf
+
+INF RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
+
+################################################################################
+[FV.PEIFV]
+FvNameGuid = 6938079B-B503-4E3D-9D24-B28337A25806
+BlockSize = 0x10000
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+APRIORI PEI {
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+}
+
+#
+# PEI Phase modules
+#
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF OvmfPkg/PlatformPei/PlatformPei.inf
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+################################################################################
+
+[FV.DXEFV]
+FvForceRebase = FALSE
+FvNameGuid = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1
+BlockSize = 0x10000
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+APRIORI DXE {
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+ INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+}
+
+#
+# DXE Phase modules
+#
+INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF OvmfPkg/8259InterruptControllerDxe/8259.inf
+INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF OvmfPkg/8254TimerDxe/8254Timer.inf
+INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF MdeModulePkg/Universal/Metronome/Metronome.inf
+INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+
+INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+INF OvmfPkg/XenBusDxe/XenBusDxe.inf
+INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF MdeModulePkg/Application/UiApp/UiApp.inf
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+INF OvmfPkg/SioBusDxe/SioBusDxe.inf
+!ifndef $(SOURCE_DEBUG_ENABLE)
+INF MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+!endif
+INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
+
+INF FatPkg/EnhancedFatDxe/Fat.inf
+INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
+
+!if $(TOOL_CHAIN_TAG) != "XCODE5"
+INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+!endif
+INF ShellPkg/Application/Shell/Shell.inf
+
+INF MdeModulePkg/Logo/LogoDxe.inf
+
+#
+# Network modules
+#
+!if $(E1000_ENABLE)
+ FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
+ SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI
+ }
+!endif
+!include NetworkPkg/Network.fdf.inc
+
+#
+# Usb Support
+#
+INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+INF OvmfPkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+INF OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+INF RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
+!endif
+
+INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+INF OvmfPkg/PlatformDxe/Platform.inf
+INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf
+INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+
+#
+# Variable driver stack (non-SMM)
+#
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+################################################################################
+
+[FV.FVMAIN_COMPACT]
+FvNameGuid = 48DB5E17-707C-472D-91CD-1613E7EF51B0
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ #
+ # These firmware volumes will have files placed in them uncompressed,
+ # and then both firmware volumes will be compressed in a single
+ # compression operation in order to achieve better overall compression.
+ #
+ SECTION FV_IMAGE = PEIFV
+ SECTION FV_IMAGE = DXEFV
+ }
+ }
+
+!include DecomprScratchEnd.fdf.inc
+
+################################################################################
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ RAW ACPI Optional |.acpi
+ RAW ASL Optional |.aml
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ }
+
+[Rule.Common.USER_DEFINED.CSM]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW BIN |.bin
+ }
+
+[Rule.Common.SEC.RESET_VECTOR]
+ FILE RAW = $(NAMED_GUID) {
+ RAW BIN Align = 16 |.bin
+ }
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 02/35] OvmfPkg: Create platform OvmfXen
2019-07-04 14:42 ` [PATCH v3 02/35] OvmfPkg: Create platform OvmfXen Anthony PERARD
@ 2019-07-05 13:29 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 13:29 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> OvmfXen is a copy of OvmfX64, removing VirtIO and some SMM.
>
> This new platform will be changed to make it works on two types of Xen
> guest: HVM and PVH.
>
> Compare to OvmfX64, this patch:
>
> - changed: PLATFORM_GUID, OUTPUT_DIRECTORY, FLASH_DEFINITION
> - removed: VirtioLib class resolution
> - removed: all UEFI_DRIVER modules for virtio devices
> - removed: DXE_SMM_DRIVER and SMM_CORE lib class resolutions
> - removed: DXE_SMM_DRIVER and SMM_CORE FDF rules
> - removed: Everything related to SMM_REQUIRE==true
> - removed: Everything related to SECURE_BOOT_ENABLE==true
> - removed: Everything related to TPM2_ENABLE==true
> - changed: PcdPciDisableBusEnumeration dynamic default flipped to TRUE
> - changed: default FD_SIZE_IN_KB to 2M.
> - reverted d272449d9e1e, "OvmfPkg: raise DXEFV size to 11 MB"
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - rebased, SPDX + 8259/8254 changes
>
> OvmfPkg/OvmfXen.dsc | 729 ++++++++++++++++++++++++++++++++++++++++++++
> OvmfPkg/OvmfXen.fdf | 439 ++++++++++++++++++++++++++
> 2 files changed, 1168 insertions(+)
> create mode 100644 OvmfPkg/OvmfXen.dsc
> create mode 100644 OvmfPkg/OvmfXen.fdf
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 03/35] OvmfPkg: Introduce XenResetVector
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
2019-07-04 14:41 ` [PATCH v3 01/35] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 02/35] OvmfPkg: Create platform OvmfXen Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 04/35] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
` (34 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Introduce XenResetVector, a copy of OvmfPkg/ResetVector, with one
changes:
- SEC_DEFAULT_CR0: enable cache (bit 30 or CD set to 0)
Xen copies the OVMF code to RAM, there is no need to disable cache.
This new module will later be modified to add a new entry point, more
detail in a following commit "OvmfPkg/XenResetVector: Add new entry point
for Xen PVH"
Value FILE_GUID of XenResetVector have not changed compare to ResetVector
because it is a special value (gEfiFirmwareVolumeTopFileGuid).
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- Added gEfiFirmwareVolumeTopFileGuid to the commit message.
- rebased: SPDX
OvmfPkg/OvmfXen.dsc | 2 +-
OvmfPkg/OvmfXen.fdf | 2 +-
OvmfPkg/XenResetVector/XenResetVector.inf | 38 +++++
.../XenResetVector/Ia16/Real16ToFlat32.asm | 134 ++++++++++++++++
OvmfPkg/XenResetVector/Ia32/PageTables64.asm | 149 ++++++++++++++++++
OvmfPkg/XenResetVector/XenResetVector.nasmb | 68 ++++++++
6 files changed, 391 insertions(+), 2 deletions(-)
create mode 100644 OvmfPkg/XenResetVector/XenResetVector.inf
create mode 100644 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
create mode 100644 OvmfPkg/XenResetVector/Ia32/PageTables64.asm
create mode 100644 OvmfPkg/XenResetVector/XenResetVector.nasmb
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 3b56815dd7..cab54da3e8 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -495,7 +495,7 @@ [PcdsDynamicDefault]
#
################################################################################
[Components]
- OvmfPkg/ResetVector/ResetVector.inf
+ OvmfPkg/XenResetVector/XenResetVector.inf
#
# SEC Phase modules
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index f59647fd14..6fc8479aae 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -118,7 +118,7 @@ [FV.SECFV]
#
INF OvmfPkg/Sec/SecMain.inf
-INF RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
+INF RuleOverride=RESET_VECTOR OvmfPkg/XenResetVector/XenResetVector.inf
################################################################################
[FV.PEIFV]
diff --git a/OvmfPkg/XenResetVector/XenResetVector.inf b/OvmfPkg/XenResetVector/XenResetVector.inf
new file mode 100644
index 0000000000..097fc9b5b4
--- /dev/null
+++ b/OvmfPkg/XenResetVector/XenResetVector.inf
@@ -0,0 +1,38 @@
+## @file
+# Reset Vector
+#
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = XenResetVector
+ FILE_GUID = 1BA0062E-C779-4582-8566-336AE8F78F09
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.1
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ XenResetVector.nasmb
+
+[Packages]
+ OvmfPkg/OvmfPkg.dec
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[BuildOptions]
+ *_*_IA32_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
+ *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
new file mode 100644
index 0000000000..5c329bfaea
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
@@ -0,0 +1,134 @@
+;------------------------------------------------------------------------------
+; @file
+; Transition from 16 bit real mode into 32 bit flat protected mode
+;
+; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+%define SEC_DEFAULT_CR0 0x00000023
+%define SEC_DEFAULT_CR4 0x640
+
+BITS 16
+
+;
+; Modified: EAX, EBX
+;
+; @param[out] DS Selector allowing flat access to all addresses
+; @param[out] ES Selector allowing flat access to all addresses
+; @param[out] FS Selector allowing flat access to all addresses
+; @param[out] GS Selector allowing flat access to all addresses
+; @param[out] SS Selector allowing flat access to all addresses
+;
+TransitionFromReal16To32BitFlat:
+
+ debugShowPostCode POSTCODE_16BIT_MODE
+
+ cli
+
+ mov bx, 0xf000
+ mov ds, bx
+
+ mov bx, ADDR16_OF(gdtr)
+
+o32 lgdt [cs:bx]
+
+ mov eax, SEC_DEFAULT_CR0
+ mov cr0, eax
+
+ jmp LINEAR_CODE_SEL:dword ADDR_OF(jumpTo32BitAndLandHere)
+BITS 32
+jumpTo32BitAndLandHere:
+
+ mov eax, SEC_DEFAULT_CR4
+ mov cr4, eax
+
+ debugShowPostCode POSTCODE_32BIT_MODE
+
+ mov ax, LINEAR_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ OneTimeCallRet TransitionFromReal16To32BitFlat
+
+ALIGN 2
+
+gdtr:
+ dw GDT_END - GDT_BASE - 1 ; GDT limit
+ dd ADDR_OF(GDT_BASE)
+
+ALIGN 16
+
+;
+; Macros for GDT entries
+;
+
+%define PRESENT_FLAG(p) (p << 7)
+%define DPL(dpl) (dpl << 5)
+%define SYSTEM_FLAG(s) (s << 4)
+%define DESC_TYPE(t) (t)
+
+; Type: data, expand-up, writable, accessed
+%define DATA32_TYPE 3
+
+; Type: execute, readable, expand-up, accessed
+%define CODE32_TYPE 0xb
+
+; Type: execute, readable, expand-up, accessed
+%define CODE64_TYPE 0xb
+
+%define GRANULARITY_FLAG(g) (g << 7)
+%define DEFAULT_SIZE32(d) (d << 6)
+%define CODE64_FLAG(l) (l << 5)
+%define UPPER_LIMIT(l) (l)
+
+;
+; The Global Descriptor Table (GDT)
+;
+
+GDT_BASE:
+; null descriptor
+NULL_SEL equ $-GDT_BASE
+ DW 0 ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB 0 ; sys flag, dpl, type
+ DB 0 ; limit 19:16, flags
+ DB 0 ; base 31:24
+
+; linear data segment descriptor
+LINEAR_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+
+; linear code segment descriptor
+LINEAR_CODE_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+
+%ifdef ARCH_X64
+; linear code (64-bit) segment descriptor
+LINEAR_CODE64_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+%endif
+
+GDT_END:
+
diff --git a/OvmfPkg/XenResetVector/Ia32/PageTables64.asm b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
new file mode 100644
index 0000000000..9f1c0e2259
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
@@ -0,0 +1,149 @@
+;------------------------------------------------------------------------------
+; @file
+; Sets the CR3 register for 64-bit paging
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 32
+
+%define PAGE_PRESENT 0x01
+%define PAGE_READ_WRITE 0x02
+%define PAGE_USER_SUPERVISOR 0x04
+%define PAGE_WRITE_THROUGH 0x08
+%define PAGE_CACHE_DISABLE 0x010
+%define PAGE_ACCESSED 0x020
+%define PAGE_DIRTY 0x040
+%define PAGE_PAT 0x080
+%define PAGE_GLOBAL 0x0100
+%define PAGE_2M_MBO 0x080
+%define PAGE_2M_PAT 0x01000
+
+%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
+ PAGE_ACCESSED + \
+ PAGE_DIRTY + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
+%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
+; Check if Secure Encrypted Virtualization (SEV) feature is enabled
+;
+; If SEV is enabled then EAX will be at least 32
+; If SEV is disabled then EAX will be zero.
+;
+CheckSevFeature:
+ ; Check if we have a valid (0x8000_001F) CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+
+ ; This check should fail on Intel or Non SEV AMD CPUs. In future if
+ ; Intel CPUs supports this CPUID leaf then we are guranteed to have exact
+ ; same bit definition.
+ cmp eax, 0x8000001f
+ jl NoSev
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc NoSev
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+ bt eax, 0
+ jnc NoSev
+
+ ; Get pte bit position to enable memory encryption
+ ; CPUID Fn8000_001F[EBX] - Bits 5:0
+ ;
+ mov eax, ebx
+ and eax, 0x3f
+ jmp SevExit
+
+NoSev:
+ xor eax, eax
+
+SevExit:
+ OneTimeCallRet CheckSevFeature
+
+;
+; Modified: EAX, EBX, ECX, EDX
+;
+SetCr3ForPageTables64:
+
+ OneTimeCall CheckSevFeature
+ xor edx, edx
+ test eax, eax
+ jz SevNotActive
+
+ ; If SEV is enabled, C-bit is always above 31
+ sub eax, 32
+ bts edx, eax
+
+SevNotActive:
+
+ ;
+ ; For OVMF, build some initial page tables at
+ ; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000).
+ ;
+ ; This range should match with PcdOvmfSecPageTablesSize which is
+ ; declared in the FDF files.
+ ;
+ ; At the end of PEI, the pages tables will be rebuilt into a
+ ; more permanent location by DxeIpl.
+ ;
+
+ mov ecx, 6 * 0x1000 / 4
+ xor eax, eax
+clearPageTablesMemoryLoop:
+ mov dword[ecx * 4 + PT_ADDR (0) - 4], eax
+ loop clearPageTablesMemoryLoop
+
+ ;
+ ; Top level Page Directory Pointers (1 * 512GB entry)
+ ;
+ mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (4)], edx
+
+ ;
+ ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)
+ ;
+ mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x1004)], edx
+ mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x100C)], edx
+ mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x1014)], edx
+ mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x101C)], edx
+
+ ;
+ ; Page Table Entries (2048 * 2MB entries => 4GB)
+ ;
+ mov ecx, 0x800
+pageTableEntriesLoop:
+ mov eax, ecx
+ dec eax
+ shl eax, 21
+ add eax, PAGE_2M_PDE_ATTR
+ mov [ecx * 8 + PT_ADDR (0x2000 - 8)], eax
+ mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
+ loop pageTableEntriesLoop
+
+ ;
+ ; Set CR3 now that the paging structures are available
+ ;
+ mov eax, PT_ADDR (0)
+ mov cr3, eax
+
+ OneTimeCallRet SetCr3ForPageTables64
diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
new file mode 100644
index 0000000000..89a4b08bc3
--- /dev/null
+++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------
+; @file
+; This file includes all other code files to assemble the reset vector code
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+;
+; If neither ARCH_IA32 nor ARCH_X64 are defined, then try to include
+; Base.h to use the C pre-processor to determine the architecture.
+;
+%ifndef ARCH_IA32
+ %ifndef ARCH_X64
+ #include <Base.h>
+ #if defined (MDE_CPU_IA32)
+ %define ARCH_IA32
+ #elif defined (MDE_CPU_X64)
+ %define ARCH_X64
+ #endif
+ %endif
+%endif
+
+%ifdef ARCH_IA32
+ %ifdef ARCH_X64
+ %error "Only one of ARCH_IA32 or ARCH_X64 can be defined."
+ %endif
+%elifdef ARCH_X64
+%else
+ %error "Either ARCH_IA32 or ARCH_X64 must be defined."
+%endif
+
+%include "CommonMacros.inc"
+
+%include "PostCodes.inc"
+
+%ifdef DEBUG_PORT80
+ %include "Port80Debug.asm"
+%elifdef DEBUG_SERIAL
+ %include "SerialDebug.asm"
+%else
+ %include "DebugDisabled.asm"
+%endif
+
+%include "Ia32/SearchForBfvBase.asm"
+%include "Ia32/SearchForSecEntry.asm"
+
+%ifdef ARCH_X64
+ #include <AutoGen.h>
+
+ %if (FixedPcdGet32 (PcdOvmfSecPageTablesSize) != 0x6000)
+ %error "This implementation inherently depends on PcdOvmfSecPageTablesSize"
+ %endif
+
+ %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
+%include "Ia32/Flat32ToFlat64.asm"
+%include "Ia32/PageTables64.asm"
+%endif
+
+%include "Ia16/Real16ToFlat32.asm"
+%include "Ia16/Init16.asm"
+
+%include "Main.asm"
+
+%include "Ia16/ResetVectorVtf0.asm"
+
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 04/35] OvmfPkg: Introduce XenPlatformPei
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (2 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 03/35] OvmfPkg: Introduce XenResetVector Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 13:53 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 05/35] OvmfPkg/OvmfXen: Creating an ELF header Anthony PERARD
` (33 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Introduce XenPlatformPei, a copy of OvmfPkg/PlatformPei without some
of QEMU specific initialization, Xen does not support QemuFwCfg.
This new module will be adjusted to accommodate Xen PVH.
fw_cfg dependents that have been removed, which are dynamically skipped
when running PlatformPei on Xen:
- GetFirstNonAddress(): controlling the 64-bit PCI MMIO aperture via the
(experimental) "opt/ovmf/X-PciMmio64Mb" file
- GetFirstNonAddress(): honoring the hotplug DIMM area
("etc/reserved-memory-end") in the placement of the 64-bit PCI MMIO
aperture
- NoexecDxeInitialization() is removed, so PcdPropertiesTableEnable and
PcdSetNxForStack are left constant FALSE (not set dynamically from
fw_cfg "opt/ovmf/PcdXxxx")
- MaxCpuCountInitialization(), PublishPeiMemory(): the max CPU count is
not taken from the QemuFwCfgItemSmpCpuCount fw_cfg key;
PcdCpuMaxLogicalProcessorNumber is used intact and
PcdCpuApInitTimeOutInMicroSeconds is never changed or used.
- InitializeXenPlatform(), S3Verification(): S3 is assumed disabled (not
consulting "etc/system-states" via QemuFwCfgS3Enabled()).
- InstallFeatureControlCallback(): the feature control MSR is not set
from "etc/msr_feature_control"
(also removed FeatureControl.c as there is nothing been executed)
Also removed:
- SMRAM/TSEG-related low mem size adjusting (PcdSmmSmramRequire is
assumed FALSE) in PublishPeiMemory(),
- QemuInitializeRam() entirely,
Xen related changes:
- Have removed the module variable mXen, as it should be always true.
- Have the platform PEI initialization fails if Xen has not been
detected.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix coding style in new code
(use DEBUG_xxx, add ASSERT before CpuDeadLoop)
- rebased, SPDX
OvmfPkg/OvmfXen.dsc | 2 +-
OvmfPkg/OvmfXen.fdf | 2 +-
OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 96 +++++
OvmfPkg/XenPlatformPei/Cmos.h | 52 +++
OvmfPkg/XenPlatformPei/Platform.h | 108 ++++++
OvmfPkg/XenPlatformPei/Xen.h | 39 ++
OvmfPkg/XenPlatformPei/AmdSev.c | 64 ++++
OvmfPkg/XenPlatformPei/ClearCache.c | 112 ++++++
OvmfPkg/XenPlatformPei/Cmos.c | 60 +++
OvmfPkg/XenPlatformPei/Fv.c | 76 ++++
OvmfPkg/XenPlatformPei/MemDetect.c | 421 ++++++++++++++++++++
OvmfPkg/XenPlatformPei/Platform.c | 444 ++++++++++++++++++++++
OvmfPkg/XenPlatformPei/Xen.c | 219 +++++++++++
13 files changed, 1693 insertions(+), 2 deletions(-)
create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf
create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
create mode 100644 OvmfPkg/XenPlatformPei/AmdSev.c
create mode 100644 OvmfPkg/XenPlatformPei/ClearCache.c
create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index cab54da3e8..9f79d455fa 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -523,7 +523,7 @@ [Components]
}
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
- OvmfPkg/PlatformPei/PlatformPei.inf
+ OvmfPkg/XenPlatformPei/XenPlatformPei.inf
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 6fc8479aae..2ceff7baa2 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -152,7 +152,7 @@ [FV.PEIFV]
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
-INF OvmfPkg/PlatformPei/PlatformPei.inf
+INF OvmfPkg/XenPlatformPei/XenPlatformPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
new file mode 100644
index 0000000000..d1265c365a
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
@@ -0,0 +1,96 @@
+## @file
+# Platform PEI driver
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = XenPlatformPei
+ FILE_GUID = f112a6ee-993a-4f0b-8295-e52029d9b4ba
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeXenPlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ AmdSev.c
+ ClearCache.c
+ Cmos.c
+ Cmos.h
+ Fv.c
+ MemDetect.c
+ Platform.c
+ Platform.h
+ Xen.c
+ Xen.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+ gEfiXenInfoGuid
+
+[LibraryClasses]
+ BaseLib
+ CacheMaintenanceLib
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ ResourcePublicationLib
+ PeiServicesLib
+ PeimEntryPoint
+ MtrrLib
+ MemEncryptSevLib
+ PcdLib
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
+ gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
+ gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid
+ gEfiPeiMpServicesPpiGuid
+
+[Depex]
+ TRUE
+
diff --git a/OvmfPkg/XenPlatformPei/Cmos.h b/OvmfPkg/XenPlatformPei/Cmos.h
new file mode 100644
index 0000000000..80ffcb002f
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Cmos.h
@@ -0,0 +1,52 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CMOS_H__
+#define __CMOS_H__
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ );
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ );
+
+
+#endif
+
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
new file mode 100644
index 0000000000..77427496c0
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -0,0 +1,108 @@
+/** @file
+ Platform PEI module include file.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_PEI_H_INCLUDED_
+#define _PLATFORM_PEI_H_INCLUDED_
+
+#include <IndustryStandard/E820.h>
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ );
+
+VOID
+AddressWidthInitialization (
+ VOID
+ );
+
+VOID
+Q35TsegMbytesInitialization (
+ VOID
+ );
+
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ );
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ );
+
+VOID
+InitializeRamRegions (
+ VOID
+ );
+
+EFI_STATUS
+PeiFvInitialization (
+ VOID
+ );
+
+VOID
+InstallClearCacheCallback (
+ VOID
+ );
+
+EFI_STATUS
+InitializeXen (
+ VOID
+ );
+
+BOOLEAN
+XenDetect (
+ VOID
+ );
+
+VOID
+AmdSevInitialize (
+ VOID
+ );
+
+VOID
+XenPublishRamRegions (
+ VOID
+ );
+
+extern EFI_BOOT_MODE mBootMode;
+
+extern UINT8 mPhysMemAddressWidth;
+
+extern UINT16 mHostBridgeDevId;
+
+#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/OvmfPkg/XenPlatformPei/Xen.h b/OvmfPkg/XenPlatformPei/Xen.h
new file mode 100644
index 0000000000..2605481280
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Xen.h
@@ -0,0 +1,39 @@
+/** @file
+ Ovmf info structure passed by Xen
+
+Copyright (c) 2013, Citrix Systems UK Ltd.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __XEN_H__
+#define __XEN_H__
+
+#include <PiPei.h>
+
+// Physical address of OVMF info
+#define OVMF_INFO_PHYSICAL_ADDRESS 0x00001000
+
+// This structure must match the definition on Xen side
+#pragma pack(1)
+typedef struct {
+ CHAR8 Signature[14]; // XenHVMOVMF\0
+ UINT8 Length; // Length of this structure
+ UINT8 Checksum; // Set such that the sum over bytes 0..length == 0
+ //
+ // Physical address of an array of TablesCount elements.
+ //
+ // Each element contains the physical address of a BIOS table.
+ //
+ EFI_PHYSICAL_ADDRESS Tables;
+ UINT32 TablesCount;
+ //
+ // Physical address of the E820 table, contains E820EntriesCount entries.
+ //
+ EFI_PHYSICAL_ADDRESS E820;
+ UINT32 E820EntriesCount;
+} EFI_XEN_OVMF_INFO;
+#pragma pack()
+
+#endif /* __XEN_H__ */
diff --git a/OvmfPkg/XenPlatformPei/AmdSev.c b/OvmfPkg/XenPlatformPei/AmdSev.c
new file mode 100644
index 0000000000..7ebbb5cc1f
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/AmdSev.c
@@ -0,0 +1,64 @@
+/**@file
+ Initialize Secure Encrypted Virtualization (SEV) support
+
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+//
+// The package level header files this module uses
+//
+#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PcdLib.h>
+#include <PiPei.h>
+#include <Register/Amd/Cpuid.h>
+#include <Register/Cpuid.h>
+
+#include "Platform.h"
+
+/**
+
+ Function checks if SEV support is available, if present then it sets
+ the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.
+
+ **/
+VOID
+AmdSevInitialize (
+ VOID
+ )
+{
+ CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx;
+ UINT64 EncryptionMask;
+ RETURN_STATUS PcdStatus;
+
+ //
+ // Check if SEV is enabled
+ //
+ if (!MemEncryptSevIsEnabled ()) {
+ return;
+ }
+
+ //
+ // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
+ //
+ AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
+ EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
+
+ //
+ // Set Memory Encryption Mask PCD
+ //
+ PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
+
+ //
+ // Set Pcd to Deny the execution of option ROM when security
+ // violation.
+ //
+ PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);
+ ASSERT_RETURN_ERROR (PcdStatus);
+}
diff --git a/OvmfPkg/XenPlatformPei/ClearCache.c b/OvmfPkg/XenPlatformPei/ClearCache.c
new file mode 100644
index 0000000000..fab53633a9
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/ClearCache.c
@@ -0,0 +1,112 @@
+/**@file
+ Install a callback to clear cache on all processors.
+ This is for conformance with the TCG "Platform Reset Attack Mitigation
+ Specification". Because clearing the CPU caches at boot doesn't impact
+ performance significantly, do it unconditionally, for simplicity's
+ sake.
+
+ Copyright (C) 2018, Red Hat, Inc.
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/MpServices.h>
+
+#include "Platform.h"
+
+/**
+ Invalidate data & instruction caches.
+ All APs execute this function in parallel. The BSP executes the function
+ separately.
+
+ @param[in,out] WorkSpace Pointer to the input/output argument workspace
+ shared by all processors.
+**/
+STATIC
+VOID
+EFIAPI
+ClearCache (
+ IN OUT VOID *WorkSpace
+ )
+{
+ WriteBackInvalidateDataCache ();
+ InvalidateInstructionCache ();
+}
+
+/**
+ Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table.
+ @param[in] NotifyDescriptor Address of the notification descriptor data
+ structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @return Status of the notification. The status code returned from this
+ function is ignored.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ClearCacheOnMpServicesAvailable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_PEI_MP_SERVICES_PPI *MpServices;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
+
+ //
+ // Clear cache on all the APs in parallel.
+ //
+ MpServices = Ppi;
+ Status = MpServices->StartupAllAPs (
+ (CONST EFI_PEI_SERVICES **)PeiServices,
+ MpServices,
+ ClearCache, // Procedure
+ FALSE, // SingleThread
+ 0, // TimeoutInMicroSeconds: inf.
+ NULL // ProcedureArgument
+ );
+ if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
+ DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ //
+ // Now clear cache on the BSP too.
+ //
+ ClearCache (NULL);
+ return EFI_SUCCESS;
+}
+
+//
+// Notification object for registering the callback, for when
+// EFI_PEI_MP_SERVICES_PPI becomes available.
+//
+STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMpServicesPpiGuid, // Guid
+ ClearCacheOnMpServicesAvailable // Notify
+};
+
+VOID
+InstallClearCacheCallback (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesNotifyPpi (&mMpServicesNotify);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to set up MP Services callback: %r\n",
+ __FUNCTION__, Status));
+ }
+}
diff --git a/OvmfPkg/XenPlatformPei/Cmos.c b/OvmfPkg/XenPlatformPei/Cmos.c
new file mode 100644
index 0000000000..5d9ee67cd8
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Cmos.c
@@ -0,0 +1,60 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Cmos.h"
+#include "Library/IoLib.h"
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ IoWrite8 (0x71, Value);
+ return Value;
+}
+
diff --git a/OvmfPkg/XenPlatformPei/Fv.c b/OvmfPkg/XenPlatformPei/Fv.c
new file mode 100644
index 0000000000..fac1ffc9fd
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Fv.c
@@ -0,0 +1,76 @@
+/** @file
+ Build FV related hobs for platform.
+
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiPei.h"
+#include "Platform.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+
+/**
+ Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
+ and DXE know about them.
+
+ @retval EFI_SUCCESS Platform PEI FVs were initialized successfully.
+
+**/
+EFI_STATUS
+PeiFvInitialization (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
+
+ //
+ // Create a memory allocation HOB for the PEI FV.
+ //
+ // Allocate as ACPI NVS is S3 is supported
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdOvmfPeiMemFvBase),
+ PcdGet32 (PcdOvmfPeiMemFvSize),
+ EfiBootServicesData
+ );
+
+ //
+ // Let DXE know about the DXE FV
+ //
+ BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
+
+ //
+ // Create a memory allocation HOB for the DXE FV.
+ //
+ // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
+ // firmware volumes at S3 resume too, hence we need to keep away the OS from
+ // DXEFV as well. Otherwise we only need to keep away DXE itself from the
+ // DXEFV area.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdOvmfDxeMemFvBase),
+ PcdGet32 (PcdOvmfDxeMemFvSize),
+ EfiBootServicesData
+ );
+
+ //
+ // Let PEI know about the DXE FV so it can find the DXE Core
+ //
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase),
+ PcdGet32 (PcdOvmfDxeMemFvSize),
+ NULL,
+ NULL
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
new file mode 100644
index 0000000000..cb7dd93ad6
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/MemDetect.c
@@ -0,0 +1,421 @@
+/**@file
+ Memory Detection for Virtual Machines.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <IndustryStandard/Q35MchIch9.h>
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+UINT8 mPhysMemAddressWidth;
+
+STATIC UINT32 mS3AcpiReservedMemoryBase;
+STATIC UINT32 mS3AcpiReservedMemorySize;
+
+STATIC UINT16 mQ35TsegMbytes;
+
+VOID
+Q35TsegMbytesInitialization (
+ VOID
+ )
+{
+ UINT16 ExtendedTsegMbytes;
+ RETURN_STATUS PcdStatus;
+
+ if (mHostBridgeDevId != INTEL_Q35_MCH_DEVICE_ID) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
+ "only DID=0x%04x (Q35) is supported\n",
+ __FUNCTION__,
+ mHostBridgeDevId,
+ INTEL_Q35_MCH_DEVICE_ID
+ ));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ //
+ // Check if QEMU offers an extended TSEG.
+ //
+ // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB
+ // register, and reading back the register.
+ //
+ // On a QEMU machine type that does not offer an extended TSEG, the initial
+ // write overwrites whatever value a malicious guest OS may have placed in
+ // the (unimplemented) register, before entering S3 or rebooting.
+ // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
+ //
+ // On a QEMU machine type that offers an extended TSEG, the initial write
+ // triggers an update to the register. Subsequently, the value read back
+ // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the
+ // number of megabytes.
+ //
+ PciWrite16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB), MCH_EXT_TSEG_MB_QUERY);
+ ExtendedTsegMbytes = PciRead16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB));
+ if (ExtendedTsegMbytes == MCH_EXT_TSEG_MB_QUERY) {
+ mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
+ return;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: QEMU offers an extended TSEG (%d MB)\n",
+ __FUNCTION__,
+ ExtendedTsegMbytes
+ ));
+ PcdStatus = PcdSet16S (PcdQ35TsegMbytes, ExtendedTsegMbytes);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ mQ35TsegMbytes = ExtendedTsegMbytes;
+}
+
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ )
+{
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8) CmosRead8 (0x34);
+ Cmos0x35 = (UINT8) CmosRead8 (0x35);
+
+ return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb (
+ )
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
+ }
+
+ return LShiftU64 (Size, 16);
+}
+
+
+/**
+ Return the highest address that DXE could possibly use, plus one.
+**/
+STATIC
+UINT64
+GetFirstNonAddress (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+ UINT64 Pci64Base, Pci64Size;
+ RETURN_STATUS PcdStatus;
+
+ FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
+
+ //
+ // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+ // resources to 32-bit anyway. See DegradeResource() in
+ // "PciResourceSupport.c".
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return FirstNonAddress;
+ }
+#endif
+
+ //
+ // Otherwise, in order to calculate the highest address plus one, we must
+ // consider the 64-bit PCI host aperture too. Fetch the default size.
+ //
+ Pci64Size = PcdGet64 (PcdPciMmio64Size);
+
+ if (Pci64Size == 0) {
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
+ __FUNCTION__));
+ PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ }
+
+ //
+ // There's nothing more to do; the amount of memory above 4GB fully
+ // determines the highest address plus one. The memory hotplug area (see
+ // below) plays no role for the firmware in this case.
+ //
+ return FirstNonAddress;
+ }
+
+ //
+ // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
+ // that the host can map it with 1GB hugepages. Follow suit.
+ //
+ Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+ Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
+
+ //
+ // The 64-bit PCI host aperture should also be "naturally" aligned. The
+ // alignment is determined by rounding the size of the aperture down to the
+ // next smaller or equal power of two. That is, align the aperture by the
+ // largest BAR size that can fit into it.
+ //
+ Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // The core PciHostBridgeDxe driver will automatically add this range to
+ // the GCD memory space map through our PciHostBridgeLib instance; here we
+ // only need to set the PCDs.
+ //
+ PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
+ __FUNCTION__, Pci64Base, Pci64Size));
+ }
+
+ //
+ // The useful address space ends with the 64-bit PCI host aperture.
+ //
+ FirstNonAddress = Pci64Base + Pci64Size;
+ return FirstNonAddress;
+}
+
+
+/**
+ Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+AddressWidthInitialization (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+
+ //
+ // As guest-physical memory size grows, the permanent PEI RAM requirements
+ // are dominated by the identity-mapping page tables built by the DXE IPL.
+ // The DXL IPL keys off of the physical address bits advertized in the CPU
+ // HOB. To conserve memory, we calculate the minimum address width here.
+ //
+ FirstNonAddress = GetFirstNonAddress ();
+ mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+
+ //
+ // If FirstNonAddress is not an integral power of two, then we need an
+ // additional bit.
+ //
+ if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
+ ++mPhysMemAddressWidth;
+ }
+
+ //
+ // The minimum address width is 36 (covers up to and excluding 64 GB, which
+ // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
+ // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
+ // can simply assert that here, since 48 bits are good enough for 256 TB.
+ //
+ if (mPhysMemAddressWidth <= 36) {
+ mPhysMemAddressWidth = 36;
+ }
+ ASSERT (mPhysMemAddressWidth <= 48);
+}
+
+
+/**
+ Calculate the cap for the permanent PEI memory.
+**/
+STATIC
+UINT32
+GetPeiMemoryCap (
+ VOID
+ )
+{
+ BOOLEAN Page1GSupport;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT32 Pml4Entries;
+ UINT32 PdpEntries;
+ UINTN TotalPages;
+
+ //
+ // If DXE is 32-bit, then just return the traditional 64 MB cap.
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return SIZE_64MB;
+ }
+#endif
+
+ //
+ // Dependent on physical address width, PEI memory allocations can be
+ // dominated by the page tables built for 64-bit DXE. So we key the cap off
+ // of those. The code below is based on CreateIdentityMappingPageTables() in
+ // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
+ //
+ Page1GSupport = FALSE;
+ if (PcdGetBool (PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ if (mPhysMemAddressWidth <= 39) {
+ Pml4Entries = 1;
+ PdpEntries = 1 << (mPhysMemAddressWidth - 30);
+ ASSERT (PdpEntries <= 0x200);
+ } else {
+ Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
+ ASSERT (Pml4Entries <= 0x200);
+ PdpEntries = 512;
+ }
+
+ TotalPages = Page1GSupport ? Pml4Entries + 1 :
+ (PdpEntries + 1) * Pml4Entries + 1;
+ ASSERT (TotalPages <= 0x40201);
+
+ //
+ // Add 64 MB for miscellaneous allocations. Note that for
+ // mPhysMemAddressWidth values close to 36, the cap will actually be
+ // dominated by this increment.
+ //
+ return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
+}
+
+
+/**
+ Publish PEI core memory
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemoryBase;
+ UINT64 MemorySize;
+ UINT32 LowerMemorySize;
+ UINT32 PeiMemoryCap;
+
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ MemoryBase = mS3AcpiReservedMemoryBase;
+ MemorySize = mS3AcpiReservedMemorySize;
+ } else {
+ PeiMemoryCap = GetPeiMemoryCap ();
+ DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
+ __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
+
+ //
+ // Determine the range of memory to use during PEI
+ //
+ MemoryBase =
+ PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
+ MemorySize = LowerMemorySize - MemoryBase;
+ if (MemorySize > PeiMemoryCap) {
+ MemoryBase = LowerMemorySize - PeiMemoryCap;
+ MemorySize = PeiMemoryCap;
+ }
+ }
+
+ //
+ // Publish this memory to the PEI Core
+ //
+ Status = PublishSystemMemory(MemoryBase, MemorySize);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+ VOID
+ )
+{
+ XenPublishRamRegions ();
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Reserve the lock box storage area
+ //
+ // Since this memory range will be used on S3 resume, it must be
+ // reserved as ACPI NVS.
+ //
+ // If S3 is unsupported, then various drivers might still write to the
+ // LockBox area. We ought to prevent DXE from serving allocation requests
+ // such that they would overlap the LockBox storage.
+ //
+ ZeroMem (
+ (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+ (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
+ );
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+ (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
+ EfiBootServicesData
+ );
+ }
+}
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
new file mode 100644
index 0000000000..c97a2fb6c1
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -0,0 +1,444 @@
+/**@file
+ Platform PEI driver
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/MasterBootMode.h>
+#include <IndustryStandard/Pci22.h>
+#include <OvmfPlatforms.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+ { EfiACPIMemoryNVS, 0x004 },
+ { EfiACPIReclaimMemory, 0x008 },
+ { EfiReservedMemoryType, 0x004 },
+ { EfiRuntimeServicesData, 0x024 },
+ { EfiRuntimeServicesCode, 0x030 },
+ { EfiBootServicesCode, 0x180 },
+ { EfiBootServicesData, 0xF00 },
+ { EfiMaxMemoryType, 0x000 }
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ }
+};
+
+
+UINT16 mHostBridgeDevId;
+
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_RESERVED,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ (Cacheable ?
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
+ 0
+ ) |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+MemMapInitialization (
+ VOID
+ )
+{
+ UINT64 PciIoBase;
+ UINT64 PciIoSize;
+ RETURN_STATUS PcdStatus;
+
+ PciIoBase = 0xC000;
+ PciIoSize = 0x4000;
+
+ //
+ // Create Memory Type Information HOB
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ mDefaultMemoryTypeInformation,
+ sizeof(mDefaultMemoryTypeInformation)
+ );
+
+ //
+ // Video memory + Legacy BIOS region
+ //
+ AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+
+ //
+ // Add PCI IO Port space available for PCI resource allocations.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+ PciIoBase,
+ PciIoSize
+ );
+ PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);
+ ASSERT_RETURN_ERROR (PcdStatus);
+}
+
+VOID
+PciExBarInitialization (
+ VOID
+ )
+{
+ union {
+ UINT64 Uint64;
+ UINT32 Uint32[2];
+ } PciExBarBase;
+
+ //
+ // We only support the 256MB size for the MMCONFIG area:
+ // 256 buses * 32 devices * 8 functions * 4096 bytes config space.
+ //
+ // The masks used below enforce the Q35 requirements that the MMCONFIG area
+ // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.
+ //
+ // Note that (b) also ensures that the minimum address width we have
+ // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice
+ // for DXE's page tables to cover the MMCONFIG area.
+ //
+ PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+ ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);
+ ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);
+
+ //
+ // Clear the PCIEXBAREN bit first, before programming the high register.
+ //
+ PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
+
+ //
+ // Program the high register. Then program the low register, setting the
+ // MMCONFIG area size and enabling decoding at once.
+ //
+ PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
+ PciWrite32 (
+ DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
+ PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
+ );
+}
+
+VOID
+MiscInitialization (
+ VOID
+ )
+{
+ UINTN PmCmd;
+ UINTN Pmba;
+ UINT32 PmbaAndVal;
+ UINT32 PmbaOrVal;
+ UINTN AcpiCtlReg;
+ UINT8 AcpiEnBit;
+ RETURN_STATUS PcdStatus;
+
+ //
+ // Disable A20 Mask
+ //
+ IoOr8 (0x92, BIT1);
+
+ //
+ // Build the CPU HOB with guest RAM size dependent address width and 16-bits
+ // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
+ // S3 resume as well, so we build it unconditionally.)
+ //
+ BuildCpuHob (mPhysMemAddressWidth, 16);
+
+ //
+ // Determine platform type and save Host Bridge DID to PCD
+ //
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+ PmbaOrVal = PIIX4_PMBA_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+ AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+ PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
+ PmbaOrVal = ICH9_PMBASE_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
+ AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, mHostBridgeDevId));
+ ASSERT (FALSE);
+ return;
+ }
+ PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ //
+ // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
+ // has been configured (e.g., by Xen) and skip the setup here.
+ // This matches the logic in AcpiTimerLibConstructor ().
+ //
+ if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
+ //
+ // The PEI phase should be exited with fully accessibe ACPI PM IO space:
+ // 1. set PMBA
+ //
+ PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
+
+ //
+ // 2. set PCICMD/IOSE
+ //
+ PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
+
+ //
+ // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
+ //
+ PciOr8 (AcpiCtlReg, AcpiEnBit);
+ }
+
+ if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+ //
+ // Set Root Complex Register Block BAR
+ //
+ PciWrite32 (
+ POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),
+ ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN
+ );
+
+ //
+ // Set PCI Express Register Range Base Address
+ //
+ PciExBarInitialization ();
+ }
+}
+
+
+VOID
+BootModeInitialization (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (CmosRead8 (0xF) == 0xFE) {
+ mBootMode = BOOT_ON_S3_RESUME;
+ }
+ CmosWrite8 (0xF, 0x00);
+
+ Status = PeiServicesSetBootMode (mBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesInstallPpi (mPpiBootMode);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+ReserveEmuVariableNvStore (
+ )
+{
+ EFI_PHYSICAL_ADDRESS VariableStore;
+ RETURN_STATUS PcdStatus;
+
+ //
+ // Allocate storage for NV variables early on so it will be
+ // at a consistent address. Since VM memory is preserved
+ // across reboots, this allows the NV variable storage to survive
+ // a VM reboot.
+ //
+ VariableStore =
+ (EFI_PHYSICAL_ADDRESS)(UINTN)
+ AllocateRuntimePages (
+ EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))
+ );
+ DEBUG ((EFI_D_INFO,
+ "Reserved variable store memory: 0x%lX; size: %dkb\n",
+ VariableStore,
+ (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
+ ));
+ PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
+ ASSERT_RETURN_ERROR (PcdStatus);
+}
+
+
+VOID
+DebugDumpCmos (
+ VOID
+ )
+{
+ UINT32 Loop;
+
+ DEBUG ((EFI_D_INFO, "CMOS:\n"));
+
+ for (Loop = 0; Loop < 0x80; Loop++) {
+ if ((Loop % 0x10) == 0) {
+ DEBUG ((EFI_D_INFO, "%02x:", Loop));
+ }
+ DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
+ if ((Loop % 0x10) == 0xf) {
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+ }
+}
+
+
+
+/**
+ Perform Platform PEI initialization.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeXenPlatform (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
+
+ DebugDumpCmos ();
+
+ if (!XenDetect ()) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Xen isn't detected\n"));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ BootModeInitialization ();
+ AddressWidthInitialization ();
+
+ //
+ // Query Host Bridge DID
+ //
+ mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
+
+ PublishPeiMemory ();
+
+ InitializeRamRegions ();
+
+ InitializeXen ();
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ ReserveEmuVariableNvStore ();
+ PeiFvInitialization ();
+ MemMapInitialization ();
+ }
+
+ InstallClearCacheCallback ();
+ AmdSevInitialize ();
+ MiscInitialization ();
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
new file mode 100644
index 0000000000..81042ab94f
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -0,0 +1,219 @@
+/**@file
+ Xen Platform PEI support
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Guid/XenInfo.h>
+#include <IndustryStandard/E820.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+
+#include "Platform.h"
+#include "Xen.h"
+
+STATIC UINT32 mXenLeaf = 0;
+
+EFI_XEN_INFO mXenInfo;
+
+/**
+ Returns E820 map provided by Xen
+
+ @param Entries Pointer to E820 map
+ @param Count Number of entries
+
+ @return EFI_STATUS
+**/
+EFI_STATUS
+XenGetE820Map (
+ EFI_E820_ENTRY64 **Entries,
+ UINT32 *Count
+ )
+{
+ EFI_XEN_OVMF_INFO *Info =
+ (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
+
+ if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {
+ return EFI_NOT_FOUND;
+ }
+
+ ASSERT (Info->E820 < MAX_ADDRESS);
+ *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;
+ *Count = Info->E820EntriesCount;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Connects to the Hypervisor.
+
+ @param XenLeaf CPUID index used to connect.
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+XenConnect (
+ UINT32 XenLeaf
+ )
+{
+ UINT32 Index;
+ UINT32 TransferReg;
+ UINT32 TransferPages;
+ UINT32 XenVersion;
+
+ AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
+ mXenInfo.HyperPages = AllocatePages (TransferPages);
+ if (!mXenInfo.HyperPages) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0; Index < TransferPages; Index++) {
+ AsmWriteMsr64 (TransferReg,
+ (UINTN) mXenInfo.HyperPages +
+ (Index << EFI_PAGE_SHIFT) + Index);
+ }
+
+ AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);
+ DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",
+ XenVersion >> 16, XenVersion & 0xFFFF));
+ mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
+ mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
+
+ /* TBD: Locate hvm_info and reserve it away. */
+ mXenInfo.HvmInfo = NULL;
+
+ BuildGuidDataHob (
+ &gEfiXenInfoGuid,
+ &mXenInfo,
+ sizeof(mXenInfo)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Figures out if we are running inside Xen HVM.
+
+ @retval TRUE Xen was detected
+ @retval FALSE Xen was not detected
+
+**/
+BOOLEAN
+XenDetect (
+ VOID
+ )
+{
+ UINT8 Signature[13];
+
+ if (mXenLeaf != 0) {
+ return TRUE;
+ }
+
+ Signature[12] = '\0';
+ for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {
+ AsmCpuid (mXenLeaf,
+ NULL,
+ (UINT32 *) &Signature[0],
+ (UINT32 *) &Signature[4],
+ (UINT32 *) &Signature[8]);
+
+ if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {
+ return TRUE;
+ }
+ }
+
+ mXenLeaf = 0;
+ return FALSE;
+}
+
+
+VOID
+XenPublishRamRegions (
+ VOID
+ )
+{
+ EFI_E820_ENTRY64 *E820Map;
+ UINT32 E820EntriesCount;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
+
+ //
+ // Parse RAM in E820 map
+ //
+ E820EntriesCount = 0;
+ Status = XenGetE820Map (&E820Map, &E820EntriesCount);
+
+ ASSERT_EFI_ERROR (Status);
+
+ if (E820EntriesCount > 0) {
+ EFI_E820_ENTRY64 *Entry;
+ UINT32 Loop;
+
+ for (Loop = 0; Loop < E820EntriesCount; Loop++) {
+ Entry = E820Map + Loop;
+
+ //
+ // Only care about RAM
+ //
+ if (Entry->Type != EfiAcpiAddressRangeMemory) {
+ continue;
+ }
+
+ AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
+
+ MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
+ }
+ }
+}
+
+
+/**
+ Perform Xen PEI initialization.
+
+ @return EFI_SUCCESS Xen initialized successfully
+ @return EFI_NOT_FOUND Not running under Xen
+
+**/
+EFI_STATUS
+InitializeXen (
+ VOID
+ )
+{
+ RETURN_STATUS PcdStatus;
+
+ if (mXenLeaf == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ XenConnect (mXenLeaf);
+
+ //
+ // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
+ // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
+ //
+ AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
+
+ PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ return EFI_SUCCESS;
+}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 04/35] OvmfPkg: Introduce XenPlatformPei
2019-07-04 14:42 ` [PATCH v3 04/35] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
@ 2019-07-05 13:53 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 13:53 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
Hi Anthony,
On 07/04/19 16:42, Anthony PERARD wrote:
> Introduce XenPlatformPei, a copy of OvmfPkg/PlatformPei without some
> of QEMU specific initialization, Xen does not support QemuFwCfg.
>
> This new module will be adjusted to accommodate Xen PVH.
>
> fw_cfg dependents that have been removed, which are dynamically skipped
> when running PlatformPei on Xen:
> - GetFirstNonAddress(): controlling the 64-bit PCI MMIO aperture via the
> (experimental) "opt/ovmf/X-PciMmio64Mb" file
> - GetFirstNonAddress(): honoring the hotplug DIMM area
> ("etc/reserved-memory-end") in the placement of the 64-bit PCI MMIO
> aperture
> - NoexecDxeInitialization() is removed, so PcdPropertiesTableEnable and
> PcdSetNxForStack are left constant FALSE (not set dynamically from
> fw_cfg "opt/ovmf/PcdXxxx")
> - MaxCpuCountInitialization(), PublishPeiMemory(): the max CPU count is
> not taken from the QemuFwCfgItemSmpCpuCount fw_cfg key;
> PcdCpuMaxLogicalProcessorNumber is used intact and
> PcdCpuApInitTimeOutInMicroSeconds is never changed or used.
> - InitializeXenPlatform(), S3Verification(): S3 is assumed disabled (not
> consulting "etc/system-states" via QemuFwCfgS3Enabled()).
> - InstallFeatureControlCallback(): the feature control MSR is not set
> from "etc/msr_feature_control"
> (also removed FeatureControl.c as there is nothing been executed)
>
> Also removed:
> - SMRAM/TSEG-related low mem size adjusting (PcdSmmSmramRequire is
> assumed FALSE) in PublishPeiMemory(),
> - QemuInitializeRam() entirely,
>
> Xen related changes:
> - Have removed the module variable mXen, as it should be always true.
> - Have the platform PEI initialization fails if Xen has not been
> detected.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> ---
>
> Notes:
> v3:
> - fix coding style in new code
> (use DEBUG_xxx, add ASSERT before CpuDeadLoop)
> - rebased, SPDX
In my v2 review at
<http://mid.mail-archive.com/994d01f3-bae7-c447-6e28-5a61a84464ac@redhat.com>,
point (2), I meant that you should please replace *all* EFI_D_xxx macros
with DEBUG_xxx macros, in new code.
By "new code" I didn't mean code that you wrote afresh, but simply
source code that appeared as new -- i.e., as an addition -- in the
patch. That is, all the EFI_D_xxx macros that you inherit from
PlatformPei by virtue of copying should be replaced as well.
This v3 patch continues to add 12 instances of EFI_D_xxx, by my count.
Please replace all of those, with DEBUG_xxx.
The rest of the updates in v3 are good, and sufficient.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 05/35] OvmfPkg/OvmfXen: Creating an ELF header
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (3 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 04/35] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 14:09 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
` (32 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
This patch changes the flash device image of OvmfXen to make it look
like it's an ELF. For this, we replace the empty embedded variable store
by a binary array, which is a ELF file header.
The ELF header explain to a loader to load the binary at the address
1MB, then jump to the PVH entry point which will be created in a later
patch. The header also includes a Xen ELF note that is part of the
PVH ABI.
That patch include OvmfXenElfHeaderGenerator.c which can be use to
regenerate the ELF header, but this will be a manual step.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- added license to generate_elf_header.c
which is renamed to OvmfPkg/OvmfXenElfHeaderGenerator.c
- added an ELF NOTE into the header
OvmfPkg/OvmfXen.fdf | 101 +++++++++++++++++++-
| 140 ++++++++++++++++++++++++++++
2 files changed, 238 insertions(+), 3 deletions(-)
create mode 100644 OvmfPkg/OvmfXenElfHeaderGenerator.c
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 2ceff7baa2..43c268f6cb 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -15,8 +15,8 @@ [Defines]
!include OvmfPkg.fdf.inc
#
-# Build the variable store and the firmware code as one unified flash device
-# image.
+# This will allow the flash device image to be recognize as an ELF, with first
+# an ELF headers, then the firmware code.
#
[FD.OVMF]
BaseAddress = $(FW_BASE_ADDRESS)
@@ -25,7 +25,102 @@ [FD.OVMF]
BlockSize = $(BLOCK_SIZE)
NumBlocks = $(FW_BLOCKS)
-!include VarStore.fdf.inc
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+0x00000000|0x0000e000
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+0x00000000|0x00040000
+!endif
+DATA = {
+ #
+ # This hex array have been generated by OvmfPkg/OvmfXenElfHeaderGenerator.c
+ # and copied manually.
+ #
+ # ELF file header
+ 0x7f, 0x45, 0x4c, 0x46, # e_ident[0..3]: Magic number
+ 0x01, # File class: 32-bit objects
+ 0x01, # Data encoding: 2's complement, little endian
+ 0x01, # File version
+ 0x03, # OS ABI identification: Object uses GNU ELF extensions
+ 0x00, # ABI version
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # e_ident[EI_PAD...]
+ 0x02, 0x00, # e_type = Executable file
+ 0x03, 0x00, # e_machine = Intel 80386
+ 0x01, 0x00, 0x00, 0x00, # e_version
+ 0xd0, 0xff, 0x2f, 0x00, # e_entry: Entry point virtual address
+ 0x34, 0x00, 0x00, 0x00, # e_phoff: Program header table file offset
+ 0x00, 0x00, 0x00, 0x00, # e_shoff: Section header table file offset
+ 0x00, 0x00, 0x00, 0x00, # e_flags: Processor-specific flags
+ 0x34, 0x00, # e_ehsize: ELF header size
+ 0x20, 0x00, # e_phentsize: Program header table entry size
+ 0x02, 0x00, # e_phnum: Program header table entry count
+ 0x00, 0x00, # e_shentsize: Section header table entry size
+ 0x00, 0x00, # e_shnum: Section header table entry count
+ 0x00, 0x00, # e_shstrndx
+
+ # ELF Program segment headers
+ # - Load segment
+ 0x01, 0x00, 0x00, 0x00, # p_type = Loadable program segment
+ 0x00, 0x00, 0x00, 0x00, # p_offset
+ 0x00, 0x00, 0x10, 0x00, # p_vaddr: Segment virtual address
+ 0x00, 0x00, 0x10, 0x00, # p_paddr: Segment physical address
+ 0x00, 0x00, 0x20, 0x00, # p_filesz: Segment size in file
+ 0x00, 0x00, 0x20, 0x00, # p_memsz: Segment size in memory
+ 0x07, 0x00, 0x00, 0x00, # p_flags = Segment is executable | writable | readable
+ 0x00, 0x00, 0x00, 0x00, # p_align
+ # - ELFNOTE segment
+ 0x04, 0x00, 0x00, 0x00, # p_type = PT_NOTE
+ 0x74, 0x00, 0x00, 0x00, # p_offset = point to XEN_ELFNOTE_PHYS32_ENTRY below
+ 0x74, 0x00, 0x10, 0x00,
+ 0x74, 0x00, 0x10, 0x00,
+ 0x14, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, # p_flags = Segment is readable
+ 0x00, 0x00, 0x00, 0x00,
+
+ # XEN_ELFNOTE_PHYS32_ENTRY
+ 0x04, 0x00, 0x00, 0x00, # name size
+ 0x04, 0x00, 0x00, 0x00, # desc size
+ 0x12, 0x00, 0x00, 0x00, # type = XEN_ELFNOTE_PHYS32_ENTRY
+ 0x58, 0x65, 0x6e, 0x00, # name = "Xen"
+ 0xd0, 0xff, 0x2f, 0x00, # desc: PVH entry point
+ 0x00
+}
+
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+0x0000e000|0x00001000
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+0x00040000|0x00001000
+!endif
+#NV_EVENT_LOG
+
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+0x0000f000|0x00001000
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+0x00041000|0x00001000
+!endif
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)
+0x00010000|0x00010000
+!endif
+!if $(FD_SIZE_IN_KB) == 4096
+0x00042000|0x00042000
+!endif
+#NV_FTW_SPARE
+
$(VARS_SIZE)|$(FVMAIN_SIZE)
FV = FVMAIN_COMPACT
--git a/OvmfPkg/OvmfXenElfHeaderGenerator.c b/OvmfPkg/OvmfXenElfHeaderGenerator.c
new file mode 100644
index 0000000000..6cbad8fbf7
--- /dev/null
+++ b/OvmfPkg/OvmfXenElfHeaderGenerator.c
@@ -0,0 +1,140 @@
+/*
+ * @file
+ * This program generates a hex array to be manually coppied into
+ * OvmfXen.fdf.
+ * The purpose is for the flash device image to be recognize as an ELF.
+ *
+ * Copyright (c) 2019, Citrix Systems, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ */
+
+#include "elf.h"
+#include "stdio.h"
+#include "stddef.h"
+
+void print_hdr(void *s, size_t size)
+{
+ char *c = s;
+
+ while (size--) {
+ printf("0x%02hhx, ", *(c++));
+ }
+}
+
+/* Format for the XEN_ELFNOTE_PHYS32_ENTRY program segment */
+#define XEN_ELFNOTE_PHYS32_ENTRY 18
+typedef struct {
+ uint32_t name_size;
+ uint32_t desc_size;
+ uint32_t type;
+ char name[4];
+ uint32_t desc;
+} xen_elfnote_phys32_entry;
+
+int main(void)
+{
+ /* FW_SIZE */
+ size_t ovmf_blob_size = 0x00200000;
+ /* Load OVMF at 1MB when running as PVH guest */
+ uint32_t ovmf_base_address = 0x00100000;
+ /* Xen PVH entry point */
+ uint32_t ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
+ size_t offset_into_file = 0;
+
+ /* ELF file header */
+ Elf32_Ehdr hdr = {
+ .e_ident = ELFMAG,
+ .e_type = ET_EXEC,
+ .e_machine = EM_386,
+ .e_version = EV_CURRENT,
+ .e_entry = ovmfxen_pvh_entry_point,
+ .e_flags = R_386_NONE,
+ .e_ehsize = sizeof (hdr),
+ .e_phentsize = sizeof (Elf32_Phdr),
+ };
+ offset_into_file += sizeof (hdr);
+
+ hdr.e_ident[EI_CLASS] = ELFCLASS32;
+ hdr.e_ident[EI_DATA] = ELFDATA2LSB;
+ hdr.e_ident[EI_VERSION] = EV_CURRENT;
+ hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
+ /* Placing program headers just after hdr */
+ hdr.e_phoff = sizeof (hdr);
+
+ /* program header */
+ Elf32_Phdr phdr_load = {
+ .p_type = PT_LOAD,
+ .p_offset = 0, /* load everything */
+ .p_paddr = ovmf_base_address,
+ .p_filesz = ovmf_blob_size,
+ .p_memsz = ovmf_blob_size,
+ .p_flags = PF_X | PF_W | PF_R,
+ .p_align = 0,
+ };
+ phdr_load.p_vaddr = phdr_load.p_paddr;
+ hdr.e_phnum += 1;
+ offset_into_file += sizeof (phdr_load);
+
+ /* Xen ELF Note. */
+
+ xen_elfnote_phys32_entry xen_elf_note = {
+ .type = XEN_ELFNOTE_PHYS32_ENTRY,
+ .name = "Xen",
+ .desc = ovmfxen_pvh_entry_point,
+ .name_size =
+ offsetof (xen_elfnote_phys32_entry, desc) -
+ offsetof (xen_elfnote_phys32_entry, name),
+ .desc_size =
+ sizeof (xen_elfnote_phys32_entry) -
+ offsetof (xen_elfnote_phys32_entry, desc),
+ };
+ Elf32_Phdr phdr_note = {
+ .p_type = PT_NOTE,
+ .p_filesz = sizeof (xen_elf_note),
+ .p_memsz = sizeof (xen_elf_note),
+ .p_flags = PF_R,
+ .p_align = 0,
+ };
+ hdr.e_phnum += 1;
+ offset_into_file += sizeof (phdr_note);
+ phdr_note.p_offset = offset_into_file;
+ phdr_note.p_paddr = ovmf_base_address + phdr_note.p_offset;
+ phdr_note.p_vaddr = phdr_note.p_paddr;
+
+
+ /*
+ * print elf header
+ */
+
+ size_t i;
+ size_t hdr_size = sizeof (hdr);
+ size_t entry_off = offsetof(typeof(hdr), e_entry);
+
+ printf("# ELF file header\n");
+ print_hdr(&hdr, entry_off);
+ printf("\n");
+ print_hdr(&hdr.e_entry, sizeof (hdr.e_entry));
+ printf(" # hdr.e_entry\n");
+ print_hdr(&hdr.e_entry + 1, hdr_size - entry_off - sizeof (hdr.e_entry));
+
+ printf("\n\n# ELF Program segment headers\n");
+ printf("# - Load segment\n");
+ for (i = 0; i < sizeof (phdr_load); i += 4) {
+ print_hdr(((char*)&phdr_load) + i, 4);
+ printf("\n");
+ }
+ printf("# - ELFNOTE segment\n");
+ for (i = 0; i < sizeof (phdr_note); i += 4) {
+ print_hdr(((char*)&phdr_note) + i, 4);
+ printf("\n");
+ }
+
+ printf("\n# XEN_ELFNOTE_PHYS32_ENTRY\n");
+ for (i = 0; i < sizeof (xen_elf_note); i += 4) {
+ print_hdr(((char*)&xen_elf_note) + i, 4);
+ printf("\n");
+ }
+
+ return 0;
+}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 05/35] OvmfPkg/OvmfXen: Creating an ELF header
2019-07-04 14:42 ` [PATCH v3 05/35] OvmfPkg/OvmfXen: Creating an ELF header Anthony PERARD
@ 2019-07-05 14:09 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 14:09 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> This patch changes the flash device image of OvmfXen to make it look
> like it's an ELF. For this, we replace the empty embedded variable store
> by a binary array, which is a ELF file header.
>
> The ELF header explain to a loader to load the binary at the address
> 1MB, then jump to the PVH entry point which will be created in a later
> patch. The header also includes a Xen ELF note that is part of the
> PVH ABI.
>
> That patch include OvmfXenElfHeaderGenerator.c which can be use to
> regenerate the ELF header, but this will be a manual step.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - added license to generate_elf_header.c
> which is renamed to OvmfPkg/OvmfXenElfHeaderGenerator.c
> - added an ELF NOTE into the header
>
> OvmfPkg/OvmfXen.fdf | 101 +++++++++++++++++++-
> OvmfPkg/OvmfXenElfHeaderGenerator.c | 140 ++++++++++++++++++++++++++++
> 2 files changed, 238 insertions(+), 3 deletions(-)
> create mode 100644 OvmfPkg/OvmfXenElfHeaderGenerator.c
[...]
> diff --git a/OvmfPkg/OvmfXenElfHeaderGenerator.c b/OvmfPkg/OvmfXenElfHeaderGenerator.c
> new file mode 100644
> index 0000000000..6cbad8fbf7
> --- /dev/null
> +++ b/OvmfPkg/OvmfXenElfHeaderGenerator.c
> @@ -0,0 +1,140 @@
> +/*
> + * @file
> + * This program generates a hex array to be manually coppied into
> + * OvmfXen.fdf.
> + * The purpose is for the flash device image to be recognize as an ELF.
> + *
> + * Copyright (c) 2019, Citrix Systems, Inc.
> + *
> + * SPDX-License-Identifier: BSD-2-Clause-Patent
> + */
(1) This patch is almost complete, just please update the comment style,
for this top-level comment, from
/*
* @file
* blah
*/
to:
/** @file
blah
**/
Please refer to e.g. "OvmfPkg/XenBusDxe/XenBusDxe.c".
With that comment style update:
Acked-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (4 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 05/35] OvmfPkg/OvmfXen: Creating an ELF header Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 13:57 ` Andrew Cooper
` (2 more replies)
2019-07-04 14:42 ` [PATCH v3 07/35] OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests Anthony PERARD
` (31 subsequent siblings)
37 siblings, 3 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD, Andrew Cooper, Roger Pau Monné
Add a new entry point for Xen PVH that enter directly in 32bits.
Information on the expected state of the machine when this entry point
is used can be found at:
https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- rebased, SPDX
- remove `cli' as via PVH the interrupts are guaranteed to be off
- rewrite some comments
.../XenResetVector/Ia16/ResetVectorVtf0.asm | 81 +++++++++++++++++++
OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 49 +++++++++++
OvmfPkg/XenResetVector/XenResetVector.nasmb | 1 +
3 files changed, 131 insertions(+)
create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
new file mode 100644
index 0000000000..958195bc5e
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
@@ -0,0 +1,81 @@
+;------------------------------------------------------------------------------
+; @file
+; First code executed by processor after resetting.
+;
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 16
+
+ALIGN 16
+
+;
+; Pad the image size to 4k when page tables are in VTF0
+;
+; If the VTF0 image has page tables built in, then we need to make
+; sure the end of VTF0 is 4k above where the page tables end.
+;
+; This is required so the page tables will be 4k aligned when VTF0 is
+; located just below 0x100000000 (4GB) in the firmware device.
+;
+%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
+ TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
+%endif
+
+BITS 32
+xenPVHEntryPoint:
+;
+; Entry point to use when running as a Xen PVH guest. (0xffffffd0)
+;
+; Description of the expected state of the machine when this entry point is
+; used can be found at:
+; https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
+;
+ jmp xenPVHMain
+
+BITS 16
+ALIGN 16
+
+applicationProcessorEntryPoint:
+;
+; Application Processors entry point
+;
+; GenFv generates code aligned on a 4k boundary which will jump to this
+; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
+; used to wake up the application processors.
+;
+ jmp EarlyApInitReal16
+
+ALIGN 8
+
+ DD 0
+
+;
+; The VTF signature
+;
+; VTF-0 means that the VTF (Volume Top File) code does not require
+; any fixups.
+;
+vtfSignature:
+ DB 'V', 'T', 'F', 0
+
+ALIGN 16
+
+resetVector:
+;
+; Reset Vector
+;
+; This is where the processor will begin execution
+;
+ nop
+ nop
+ jmp EarlyBspInitReal16
+
+ALIGN 16
+
+fourGigabytes:
+
diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
new file mode 100644
index 0000000000..2a17fed52f
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------
+; @file
+; An entry point use by Xen when a guest is started in PVH mode.
+;
+; Copyright (c) 2019, Citrix Systems, Inc.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 32
+
+xenPVHMain:
+ ;
+ ; 'BP' to indicate boot-strap processor
+ ;
+ mov di, 'BP'
+
+ ;
+ ; ESP will be used as initial value of the EAX register
+ ; in Main.asm
+ ;
+ xor esp, esp
+
+ mov ebx, ADDR_OF(gdtr)
+ lgdt [ebx]
+
+ mov eax, SEC_DEFAULT_CR0
+ mov cr0, eax
+
+ jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
+.jmpToNewCodeSeg:
+
+ mov eax, SEC_DEFAULT_CR4
+ mov cr4, eax
+
+ mov ax, LINEAR_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;
+ ; Jump to the main routine of the pre-SEC code
+ ; skiping the 16-bit part of the routine and
+ ; into the 32-bit flat mode part
+ ;
+ OneTimeCallRet TransitionFromReal16To32BitFlat
diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
index 89a4b08bc3..0dbc4f2c1d 100644
--- a/OvmfPkg/XenResetVector/XenResetVector.nasmb
+++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
@@ -63,6 +63,7 @@
%include "Ia16/Init16.asm"
%include "Main.asm"
+%include "Ia32/XenPVHMain.asm"
%include "Ia16/ResetVectorVtf0.asm"
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-04 14:42 ` [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
@ 2019-07-05 13:57 ` Andrew Cooper
2019-07-19 10:20 ` Anthony PERARD
2019-07-05 14:14 ` Laszlo Ersek
2019-07-15 11:46 ` Roger Pau Monné
2 siblings, 1 reply; 90+ messages in thread
From: Andrew Cooper @ 2019-07-05 13:57 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Roger Pau Monné
On 04/07/2019 15:42, Anthony PERARD wrote:
> Add a new entry point for Xen PVH that enter directly in 32bits.
>
> Information on the expected state of the machine when this entry point
> is used can be found at:
> https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - rebased, SPDX
> - remove `cli' as via PVH the interrupts are guaranteed to be off
> - rewrite some comments
Thanks - this is easier to follow. Some further questions.
> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> new file mode 100644
> index 0000000000..958195bc5e
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> +vtfSignature:
> + DB 'V', 'T', 'F', 0
> +
> +ALIGN 16
> +
> +resetVector:
> +;
> +; Reset Vector
> +;
> +; This is where the processor will begin execution
> +;
> + nop
> + nop
Why two nops?
> + jmp EarlyBspInitReal16
> +
> +ALIGN 16
> +
> +fourGigabytes:
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> new file mode 100644
> index 0000000000..2a17fed52f
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -0,0 +1,49 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; An entry point use by Xen when a guest is started in PVH mode.
> +;
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS 32
> +
> +xenPVHMain:
> + ;
> + ; 'BP' to indicate boot-strap processor
Indicate to what?
> + ;
> + mov di, 'BP'
> +
> + ;
> + ; ESP will be used as initial value of the EAX register
> + ; in Main.asm
> + ;
> + xor esp, esp
> +
> + mov ebx, ADDR_OF(gdtr)
> + lgdt [ebx]
lgdt [ADDR_OF(gdtr)]
should work fine, because you're in 32bit mode.
More importantly for PVH however, you don't clobber the start_info pointer.
> +
> + mov eax, SEC_DEFAULT_CR0
> + mov cr0, eax
> +
> + jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
> +.jmpToNewCodeSeg:
Does 1f (or some equivalent) not work, or is this against the coding style?
> +
> + mov eax, SEC_DEFAULT_CR4
> + mov cr4, eax
> +
> + mov ax, LINEAR_SEL
> + mov ds, ax
> + mov es, ax
> + mov fs, ax
> + mov gs, ax
> + mov ss, ax
Use eax rather than ax. The instruction decode will be much happier
with the result, and it results in shorter assembled code.
> +
> + ;
> + ; Jump to the main routine of the pre-SEC code
> + ; skiping the 16-bit part of the routine and
> + ; into the 32-bit flat mode part
> + ;
> + OneTimeCallRet TransitionFromReal16To32BitFlat
Thanks. This is far easier to follow.
~Andrew
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-05 13:57 ` Andrew Cooper
@ 2019-07-19 10:20 ` Anthony PERARD
2019-07-19 14:33 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-19 10:20 UTC (permalink / raw)
To: Andrew Cooper
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Roger Pau Monné
On Fri, Jul 05, 2019 at 02:57:06PM +0100, Andrew Cooper wrote:
> On 04/07/2019 15:42, Anthony PERARD wrote:
> > diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> > new file mode 100644
> > index 0000000000..958195bc5e
> > --- /dev/null
> > +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> > +vtfSignature:
> > + DB 'V', 'T', 'F', 0
> > +
> > +ALIGN 16
> > +
> > +resetVector:
> > +;
> > +; Reset Vector
> > +;
> > +; This is where the processor will begin execution
> > +;
> > + nop
> > + nop
>
> Why two nops?
I don't know, this is existing code that I duplicated to allow adding a
new entry point. (I wanted to use --find-copies-harder when sending the
patch, but forgot this time. This part of the chunk would not be there.)
> > + jmp EarlyBspInitReal16
> > +
> > +ALIGN 16
> > +
> > +fourGigabytes:
> > +
> > diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> > new file mode 100644
> > index 0000000000..2a17fed52f
> > --- /dev/null
> > +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> > @@ -0,0 +1,49 @@
> > +;------------------------------------------------------------------------------
> > +; @file
> > +; An entry point use by Xen when a guest is started in PVH mode.
> > +;
> > +; Copyright (c) 2019, Citrix Systems, Inc.
> > +;
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +BITS 32
> > +
> > +xenPVHMain:
> > + ;
> > + ; 'BP' to indicate boot-strap processor
>
> Indicate to what?
According to UefiCpuPkg/ResetVector/Vtf0/ReadMe.txt, that's a parameter
for the SEC image that this ResetVector locates then run.
> > + ;
> > + mov di, 'BP'
> > +
> > + ;
> > + ; ESP will be used as initial value of the EAX register
> > + ; in Main.asm
> > + ;
> > + xor esp, esp
> > +
> > + mov ebx, ADDR_OF(gdtr)
> > + lgdt [ebx]
>
> lgdt [ADDR_OF(gdtr)]
>
> should work fine, because you're in 32bit mode.
Yes, that worked fine, but a subsequent patch is going to want to modify
the gdtr address, so I've been lazy and didn't use lgdt [ADDR_OF()]
here.
See: OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH
https://patchew.org/EDK2/20190704144233.27968-1-anthony.perard@citrix.com/20190704144233.27968-9-anthony.perard@citrix.com/
> More importantly for PVH however, you don't clobber the start_info pointer.
I will actually save the start_info pointer before setting the gdt, but
that's done in a different patch:
OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests
https://patchew.org/EDK2/20190704144233.27968-1-anthony.perard@citrix.com/20190704144233.27968-8-anthony.perard@citrix.com/
> > +
> > + mov eax, SEC_DEFAULT_CR0
> > + mov cr0, eax
> > +
> > + jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
> > +.jmpToNewCodeSeg:
>
> Does 1f (or some equivalent) not work, or is this against the coding style?
I didn't find the ${label}f syntax when reading the NASM manual. But
using .${label} would be the closest. Those labels starting with a dot
are called local labels. The actual full label, if one want to use it
from anywhere, would be "XenPVHMain.jmpToNewCodeSeg" here.
> > +
> > + mov eax, SEC_DEFAULT_CR4
> > + mov cr4, eax
> > +
> > + mov ax, LINEAR_SEL
> > + mov ds, ax
> > + mov es, ax
> > + mov fs, ax
> > + mov gs, ax
> > + mov ss, ax
>
> Use eax rather than ax. The instruction decode will be much happier
> with the result, and it results in shorter assembled code.
I look into that.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-19 10:20 ` Anthony PERARD
@ 2019-07-19 14:33 ` Laszlo Ersek
2019-07-19 14:41 ` Andrew Cooper
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-19 14:33 UTC (permalink / raw)
To: Anthony PERARD, Andrew Cooper
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Roger Pau Monné
On 07/19/19 12:20, Anthony PERARD wrote:
> On Fri, Jul 05, 2019 at 02:57:06PM +0100, Andrew Cooper wrote:
>> On 04/07/2019 15:42, Anthony PERARD wrote:
>>> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>>> new file mode 100644
>>> index 0000000000..958195bc5e
>>> --- /dev/null
>>> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>>> +vtfSignature:
>>> + DB 'V', 'T', 'F', 0
>>> +
>>> +ALIGN 16
>>> +
>>> +resetVector:
>>> +;
>>> +; Reset Vector
>>> +;
>>> +; This is where the processor will begin execution
>>> +;
>>> + nop
>>> + nop
>>
>> Why two nops?
>
> I don't know, this is existing code that I duplicated to allow adding a
> new entry point. (I wanted to use --find-copies-harder when sending the
> patch, but forgot this time.
Not a big problem; while reviewing v3, I did such comparisons myself, in
my local clone. Feel free to skip "--find-copies-harder" when posting v4
too; I think there isn't much churn going on in parallel right now.
However, a new request for v4: please make sure that the new modules /
paths introduced by this patch set are covered in Maintainers.txt.
> This part of the chunk would not be there.)
Regarding the NOPs: all I can tell you is that they originate from
commit 8332983e2e33 ("UefiCpuPkg: Replace the un-necessary WBINVD
instruction at the reset vector with two NOPs in VTF0.", 2011-08-04).
Whether that change made sense back then, let alone if it makes sense
now: no clue.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-19 14:33 ` Laszlo Ersek
@ 2019-07-19 14:41 ` Andrew Cooper
2019-07-19 15:51 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: Andrew Cooper @ 2019-07-19 14:41 UTC (permalink / raw)
To: Laszlo Ersek, Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Roger Pau Monné
On 19/07/2019 15:33, Laszlo Ersek wrote:
> On 07/19/19 12:20, Anthony PERARD wrote:
>> On Fri, Jul 05, 2019 at 02:57:06PM +0100, Andrew Cooper wrote:
>>> On 04/07/2019 15:42, Anthony PERARD wrote:
>>>> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>>>> new file mode 100644
>>>> index 0000000000..958195bc5e
>>>> --- /dev/null
>>>> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>>>> +vtfSignature:
>>>> + DB 'V', 'T', 'F', 0
>>>> +
>>>> +ALIGN 16
>>>> +
>>>> +resetVector:
>>>> +;
>>>> +; Reset Vector
>>>> +;
>>>> +; This is where the processor will begin execution
>>>> +;
>>>> + nop
>>>> + nop
>>> Why two nops?
>> I don't know, this is existing code that I duplicated to allow adding a
>> new entry point. (I wanted to use --find-copies-harder when sending the
>> patch, but forgot this time.
> Not a big problem; while reviewing v3, I did such comparisons myself, in
> my local clone. Feel free to skip "--find-copies-harder" when posting v4
> too; I think there isn't much churn going on in parallel right now.
>
> However, a new request for v4: please make sure that the new modules /
> paths introduced by this patch set are covered in Maintainers.txt.
>
>> This part of the chunk would not be there.)
> Regarding the NOPs: all I can tell you is that they originate from
> commit 8332983e2e33 ("UefiCpuPkg: Replace the un-necessary WBINVD
> instruction at the reset vector with two NOPs in VTF0.", 2011-08-04).
>
> Whether that change made sense back then, let alone if it makes sense
> now: no clue.
Dropping wbinvd makes sense, because when virtualised, the caches (and
paging for that matter) are always up and running correctly. Its an
unnecessary vmexit for something which the hypervisor will nop out anyway.
Leaving two nops behind makes no sense at all.
~Andrew
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-19 14:41 ` Andrew Cooper
@ 2019-07-19 15:51 ` Anthony PERARD
0 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-19 15:51 UTC (permalink / raw)
To: Andrew Cooper
Cc: Laszlo Ersek, devel, xen-devel, Ard Biesheuvel, Jordan Justen,
Julien Grall, Roger Pau Monné
On Fri, Jul 19, 2019 at 03:41:52PM +0100, Andrew Cooper wrote:
> On 19/07/2019 15:33, Laszlo Ersek wrote:
> > On 07/19/19 12:20, Anthony PERARD wrote:
> >> On Fri, Jul 05, 2019 at 02:57:06PM +0100, Andrew Cooper wrote:
> >>> On 04/07/2019 15:42, Anthony PERARD wrote:
> >>>> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> >>>> new file mode 100644
> >>>> index 0000000000..958195bc5e
> >>>> --- /dev/null
> >>>> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> >>>> +vtfSignature:
> >>>> + DB 'V', 'T', 'F', 0
> >>>> +
> >>>> +ALIGN 16
> >>>> +
> >>>> +resetVector:
> >>>> +;
> >>>> +; Reset Vector
> >>>> +;
> >>>> +; This is where the processor will begin execution
> >>>> +;
> >>>> + nop
> >>>> + nop
> >>> Why two nops?
> >> I don't know, this is existing code that I duplicated to allow adding a
> >> new entry point. (I wanted to use --find-copies-harder when sending the
> >> patch, but forgot this time.
> > Not a big problem; while reviewing v3, I did such comparisons myself, in
> > my local clone. Feel free to skip "--find-copies-harder" when posting v4
> > too; I think there isn't much churn going on in parallel right now.
> >
> > However, a new request for v4: please make sure that the new modules /
> > paths introduced by this patch set are covered in Maintainers.txt.
Will do.
> >> This part of the chunk would not be there.)
> > Regarding the NOPs: all I can tell you is that they originate from
> > commit 8332983e2e33 ("UefiCpuPkg: Replace the un-necessary WBINVD
> > instruction at the reset vector with two NOPs in VTF0.", 2011-08-04).
> >
> > Whether that change made sense back then, let alone if it makes sense
> > now: no clue.
>
> Dropping wbinvd makes sense, because when virtualised, the caches (and
> paging for that matter) are always up and running correctly. Its an
> unnecessary vmexit for something which the hypervisor will nop out anyway.
>
> Leaving two nops behind makes no sense at all.
I'll remove the nops.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-04 14:42 ` [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
2019-07-05 13:57 ` Andrew Cooper
@ 2019-07-05 14:14 ` Laszlo Ersek
2019-07-15 11:46 ` Roger Pau Monné
2 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 14:14 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On 07/04/19 16:42, Anthony PERARD wrote:
> Add a new entry point for Xen PVH that enter directly in 32bits.
>
> Information on the expected state of the machine when this entry point
> is used can be found at:
> https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - rebased, SPDX
> - remove `cli' as via PVH the interrupts are guaranteed to be off
> - rewrite some comments
>
> .../XenResetVector/Ia16/ResetVectorVtf0.asm | 81 +++++++++++++++++++
> OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 49 +++++++++++
> OvmfPkg/XenResetVector/XenResetVector.nasmb | 1 +
> 3 files changed, 131 insertions(+)
> create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
Acked-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-04 14:42 ` [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
2019-07-05 13:57 ` Andrew Cooper
2019-07-05 14:14 ` Laszlo Ersek
@ 2019-07-15 11:46 ` Roger Pau Monné
2019-07-15 11:50 ` Andrew Cooper
2019-07-19 14:00 ` Anthony PERARD
2 siblings, 2 replies; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-15 11:46 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Thu, Jul 04, 2019 at 03:42:04PM +0100, Anthony PERARD wrote:
> Add a new entry point for Xen PVH that enter directly in 32bits.
>
> Information on the expected state of the machine when this entry point
> is used can be found at:
> https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Thanks for doing this! My knowledge of nasm is very limited, so some
of the above comments might be completely wrong.
> ---
>
> Notes:
> v3:
> - rebased, SPDX
> - remove `cli' as via PVH the interrupts are guaranteed to be off
> - rewrite some comments
>
> .../XenResetVector/Ia16/ResetVectorVtf0.asm | 81 +++++++++++++++++++
> OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 49 +++++++++++
> OvmfPkg/XenResetVector/XenResetVector.nasmb | 1 +
> 3 files changed, 131 insertions(+)
> create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
>
> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> new file mode 100644
> index 0000000000..958195bc5e
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> @@ -0,0 +1,81 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; First code executed by processor after resetting.
> +;
> +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
Extraneous <BR> tag?
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS 16
> +
> +ALIGN 16
Do you need the BITS and ALIGN here?
Isn't it enough with the BITS 32 below for the entry point, since DB
is already explicitly sized?
> +
> +;
> +; Pad the image size to 4k when page tables are in VTF0
> +;
> +; If the VTF0 image has page tables built in, then we need to make
> +; sure the end of VTF0 is 4k above where the page tables end.
> +;
> +; This is required so the page tables will be 4k aligned when VTF0 is
> +; located just below 0x100000000 (4GB) in the firmware device.
> +;
> +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
> + TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
What's the meaning of 0x1000 here?
> +%endif
> +
> +BITS 32
> +xenPVHEntryPoint:
> +;
> +; Entry point to use when running as a Xen PVH guest. (0xffffffd0)
Shouldn't this positioning be set on the linker script instead?
> +;
> +; Description of the expected state of the machine when this entry point is
> +; used can be found at:
> +; https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
> +;
> + jmp xenPVHMain
> +
> +BITS 16
> +ALIGN 16
Is it really needed to specify both?
I would assume that setting BITS 16 will already set a suitable
alignment.
> +
> +applicationProcessorEntryPoint:
> +;
> +; Application Processors entry point
> +;
> +; GenFv generates code aligned on a 4k boundary which will jump to this
> +; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
Also, if xenPVHEntryPoint is at 0x...d0, how can
applicationProcessorEntryPoint be at 0x...e0, I guess there's some
other code I'm missing that either adds padding between both, or
places them in different sections on the resulting binary image?
> +; used to wake up the application processors.
> +;
> + jmp EarlyApInitReal16
> +
> +ALIGN 8
> +
> + DD 0
Can you remove this DD...
> +
> +;
> +; The VTF signature
> +;
> +; VTF-0 means that the VTF (Volume Top File) code does not require
> +; any fixups.
> +;
> +vtfSignature:
> + DB 'V', 'T', 'F', 0
And instead do DB 0, 0, 0, 0, 'V',...?
In any case I'm not sure of the point of setting align to 8 and then
writing 32bits of 0s (but again maybe I'm just misreading the code).
Maybe you just want to set align to 32 and write the vtf signature?
> +
> +ALIGN 16
> +
> +resetVector:
> +;
> +; Reset Vector
> +;
> +; This is where the processor will begin execution
> +;
> + nop
> + nop
> + jmp EarlyBspInitReal16
> +
> +ALIGN 16
> +
> +fourGigabytes:
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> new file mode 100644
> index 0000000000..2a17fed52f
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -0,0 +1,49 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; An entry point use by Xen when a guest is started in PVH mode.
> +;
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS 32
> +
> +xenPVHMain:
> + ;
> + ; 'BP' to indicate boot-strap processor
> + ;
> + mov di, 'BP'
> +
> + ;
> + ; ESP will be used as initial value of the EAX register
> + ; in Main.asm
> + ;
> + xor esp, esp
> +
> + mov ebx, ADDR_OF(gdtr)
> + lgdt [ebx]
> +
> + mov eax, SEC_DEFAULT_CR0
> + mov cr0, eax
> +
> + jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
> +.jmpToNewCodeSeg:
> +
> + mov eax, SEC_DEFAULT_CR4
> + mov cr4, eax
> +
> + mov ax, LINEAR_SEL
> + mov ds, ax
> + mov es, ax
> + mov fs, ax
> + mov gs, ax
> + mov ss, ax
> +
> + ;
> + ; Jump to the main routine of the pre-SEC code
> + ; skiping the 16-bit part of the routine and
> + ; into the 32-bit flat mode part
> + ;
> + OneTimeCallRet TransitionFromReal16To32BitFlat
Since PVH already starts in flat 32bit mode, I'm not sure I see the
point of this routine, since it seems to be used exclusively to switch
from 16 to 32b flat mode. The comment mentions skipping that part, but
I'm not sure I see how that's achieved.
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-15 11:46 ` Roger Pau Monné
@ 2019-07-15 11:50 ` Andrew Cooper
2019-07-15 14:25 ` Roger Pau Monné
2019-07-19 14:00 ` Anthony PERARD
1 sibling, 1 reply; 90+ messages in thread
From: Andrew Cooper @ 2019-07-15 11:50 UTC (permalink / raw)
To: Roger Pau Monné, Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall
On 15/07/2019 12:46, Roger Pau Monné wrote:
>> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
>> new file mode 100644
>> index 0000000000..2a17fed52f
>> --- /dev/null
>> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
>> @@ -0,0 +1,49 @@
>> +;------------------------------------------------------------------------------
>> +; @file
>> +; An entry point use by Xen when a guest is started in PVH mode.
>> +;
>> +; Copyright (c) 2019, Citrix Systems, Inc.
>> +;
>> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>> +;
>> +;------------------------------------------------------------------------------
>> +
>> +BITS 32
>> +
>> +xenPVHMain:
>> + ;
>> + ; 'BP' to indicate boot-strap processor
>> + ;
>> + mov di, 'BP'
>> +
>> + ;
>> + ; ESP will be used as initial value of the EAX register
>> + ; in Main.asm
>> + ;
>> + xor esp, esp
>> +
>> + mov ebx, ADDR_OF(gdtr)
>> + lgdt [ebx]
>> +
>> + mov eax, SEC_DEFAULT_CR0
>> + mov cr0, eax
>> +
>> + jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
>> +.jmpToNewCodeSeg:
>> +
>> + mov eax, SEC_DEFAULT_CR4
>> + mov cr4, eax
>> +
>> + mov ax, LINEAR_SEL
>> + mov ds, ax
>> + mov es, ax
>> + mov fs, ax
>> + mov gs, ax
>> + mov ss, ax
>> +
>> + ;
>> + ; Jump to the main routine of the pre-SEC code
>> + ; skiping the 16-bit part of the routine and
>> + ; into the 32-bit flat mode part
>> + ;
>> + OneTimeCallRet TransitionFromReal16To32BitFlat
> Since PVH already starts in flat 32bit mode, I'm not sure I see the
> point of this routine, since it seems to be used exclusively to switch
> from 16 to 32b flat mode. The comment mentions skipping that part, but
> I'm not sure I see how that's achieved.
Its some OVMF local magic. This means "jmp
end_of_TransitionFromReal16To32BitFlat", which is the correct place to
go, but the code really is misleading to read.
~Andrew
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-15 11:50 ` Andrew Cooper
@ 2019-07-15 14:25 ` Roger Pau Monné
0 siblings, 0 replies; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-15 14:25 UTC (permalink / raw)
To: Andrew Cooper
Cc: Anthony PERARD, devel, xen-devel, Ard Biesheuvel, Jordan Justen,
Laszlo Ersek, Julien Grall
On Mon, Jul 15, 2019 at 12:50:29PM +0100, Andrew Cooper wrote:
> On 15/07/2019 12:46, Roger Pau Monné wrote:
> >> + ;
> >> + ; Jump to the main routine of the pre-SEC code
> >> + ; skiping the 16-bit part of the routine and
> >> + ; into the 32-bit flat mode part
> >> + ;
> >> + OneTimeCallRet TransitionFromReal16To32BitFlat
> > Since PVH already starts in flat 32bit mode, I'm not sure I see the
> > point of this routine, since it seems to be used exclusively to switch
> > from 16 to 32b flat mode. The comment mentions skipping that part, but
> > I'm not sure I see how that's achieved.
>
> Its some OVMF local magic. This means "jmp
> end_of_TransitionFromReal16To32BitFlat", which is the correct place to
> go, but the code really is misleading to read.
Oh right, it's OneTimeCallRet. I guess this is obvious if you are
familiar with OVMF code, which I'm not. Expanding the comment to
mention that jumping to the end of the routine is achieved by using
OneTimeCallRet would have helped me, but this might be too verbose.
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
2019-07-15 11:46 ` Roger Pau Monné
2019-07-15 11:50 ` Andrew Cooper
@ 2019-07-19 14:00 ` Anthony PERARD
1 sibling, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-19 14:00 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Mon, Jul 15, 2019 at 01:46:57PM +0200, Roger Pau Monné wrote:
> On Thu, Jul 04, 2019 at 03:42:04PM +0100, Anthony PERARD wrote:
> > diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> > new file mode 100644
> > index 0000000000..958195bc5e
> > --- /dev/null
> > +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> > @@ -0,0 +1,81 @@
> > +;------------------------------------------------------------------------------
> > +; @file
> > +; First code executed by processor after resetting.
> > +;
> > +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
>
> Extraneous <BR> tag?
Maybe, but I can't change that. Blame the copyright owner ;-). I think
"All rights reserved." could also be removed, or may not apply
(anymore), but that's not something that this patch series can do and
not something I'm going to do :).
> > +; Copyright (c) 2019, Citrix Systems, Inc.
> > +;
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +BITS 16
> > +
> > +ALIGN 16
>
> Do you need the BITS and ALIGN here?
>
> Isn't it enough with the BITS 32 below for the entry point, since DB
> is already explicitly sized?
Maybe, but those were already there, so I don't feel comfortable
removing/changing them, or investigating.
FYI, I wanted to send this patch series with --find-copies-harder, but
failed. That chunk would have been instead:
diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
similarity index 72%
copy from UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
copy to OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
index 7538192876..958195bc5e 100644
--- a/UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
@@ -3,6 +3,8 @@
; First code executed by processor after resetting.
;
; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+;
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
;------------------------------------------------------------------------------
@@ -21,9 +23,23 @@ ALIGN 16
; located just below 0x100000000 (4GB) in the firmware device.
;
%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
- TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
+ TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
%endif
+BITS 32
+xenPVHEntryPoint:
+;
+; Entry point to use when running as a Xen PVH guest. (0xffffffd0)
+;
+; Description of the expected state of the machine when this entry point is
+; used can be found at:
+; https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
+;
+ jmp xenPVHMain
+
+BITS 16
+ALIGN 16
+
applicationProcessorEntryPoint:
;
; Application Processors entry point
> > +
> > +;
> > +; Pad the image size to 4k when page tables are in VTF0
> > +;
> > +; If the VTF0 image has page tables built in, then we need to make
> > +; sure the end of VTF0 is 4k above where the page tables end.
> > +;
> > +; This is required so the page tables will be 4k aligned when VTF0 is
> > +; located just below 0x100000000 (4GB) in the firmware device.
> > +;
> > +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
> > + TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
>
> What's the meaning of 0x1000 here?
I don't know. I tried to figure out, but couldn't find a useful answer.
I don't know enough about the build system to figure out how this module
gets build and how it is place exactly where it needs to be.
> > +%endif
> > +
> > +BITS 32
> > +xenPVHEntryPoint:
> > +;
> > +; Entry point to use when running as a Xen PVH guest. (0xffffffd0)
>
> Shouldn't this positioning be set on the linker script instead?
There is no such thing, at least not in a position that would be useful
for us. That code might be built into an ELF, but then that ELF (or just
the code maybe) gets packaged into a module that gets packaged into a FV
(firmware volume I think), which gets packaged into a flash device
image. (Hopefully, I'm not to far from the reality.)
> > +;
> > +; Description of the expected state of the machine when this entry point is
> > +; used can be found at:
> > +; https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
> > +;
> > + jmp xenPVHMain
> > +
> > +BITS 16
> > +ALIGN 16
>
> Is it really needed to specify both?
I don't know, better safe than sorry.
> I would assume that setting BITS 16 will already set a suitable
> alignment.
I'm guessing they do have different meaning, one doesn't set the other.
I could try to find out in the NASM manual if you really want to know.
Now that I've read what ALIGN mean (see below), they are both needed.
BITS to switch to 16bits machine code, ALIGN so that the next
instruction will be aligned.
> > +
> > +applicationProcessorEntryPoint:
> > +;
> > +; Application Processors entry point
> > +;
> > +; GenFv generates code aligned on a 4k boundary which will jump to this
> > +; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
>
> Also, if xenPVHEntryPoint is at 0x...d0, how can
> applicationProcessorEntryPoint be at 0x...e0, I guess there's some
> other code I'm missing that either adds padding between both, or
> places them in different sections on the resulting binary image?
Maybe xenPVHEntryPoint isn't at 0x..d0 ... and I'm lucky that what is
before it is padding. applicationProcessorEntryPoint should be at
0x..e0.
After looking at the assembly generated by nasm, I had a look at the
documentation of ALIGN
https://www.nasm.us/doc/nasmdoc4.html#section-4.11.13
ALIGN 16 is where the magic happen. When that macro is used, the next
thing is going to be on 0xXXX0 address. So ALIGN 16 is the thing adding
padding between the jmp in xenPVHEntryPoint and the first instruction in
applicationProcessorEntryPoint.
> > +; used to wake up the application processors.
> > +;
> > + jmp EarlyApInitReal16
> > +
> > +ALIGN 8
> > +
> > + DD 0
>
> Can you remove this DD...
>
> > +
> > +;
> > +; The VTF signature
> > +;
> > +; VTF-0 means that the VTF (Volume Top File) code does not require
> > +; any fixups.
> > +;
> > +vtfSignature:
> > + DB 'V', 'T', 'F', 0
>
> And instead do DB 0, 0, 0, 0, 'V',...?
>
> In any case I'm not sure of the point of setting align to 8 and then
> writing 32bits of 0s (but again maybe I'm just misreading the code).
> Maybe you just want to set align to 32 and write the vtf signature?
ALIGN might have a different meaning that what you think it has, see
above. Also, I don't really want to change the code that was there
before without a good enough reason, see the new diff that I've copied
above, the VTF thing was already there.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 07/35] OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (5 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 06/35] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 14:24 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH Anthony PERARD
` (30 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
As described in the Xen PVH documentation [1], "ebx: contains the
physical memory address where the loader has placed the boot start info
structure". To have this pointer saved to be able to use it later in the
PEI phase, we allocate some space in the MEMFD for it. We use 'XPVH' as
a signature (for "Xen PVH").
[1] https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- rename PcdXenStartOfDay* to PcdXenPvhStartOfDay*
- Use first available token value for those (0x17 and 0x28)
OvmfPkg/OvmfPkg.dec | 3 +++
OvmfPkg/OvmfXen.fdf | 4 ++++
OvmfPkg/XenResetVector/XenResetVector.inf | 3 +++
OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 6 ++++++
OvmfPkg/XenResetVector/XenResetVector.nasmb | 2 ++
5 files changed, 18 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 9640360f62..c2a2ebfb95 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -218,6 +218,9 @@ [PcdsFixedAtBuild]
# The value should be a multiple of 4KB.
gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize|0x400000|UINT32|0x31
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr|0x0|UINT32|0x17
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize|0x0|UINT32|0x32
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 43c268f6cb..49997fee9b 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -172,6 +172,10 @@ [FD.MEMFD]
0x007000|0x001000
gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+0x008000|0x001000
+# Used by XenResetVector to communicate with XenPlatformPei
+gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr|gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
+
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
diff --git a/OvmfPkg/XenResetVector/XenResetVector.inf b/OvmfPkg/XenResetVector/XenResetVector.inf
index 097fc9b5b4..46b133a834 100644
--- a/OvmfPkg/XenResetVector/XenResetVector.inf
+++ b/OvmfPkg/XenResetVector/XenResetVector.inf
@@ -36,3 +36,6 @@ [BuildOptions]
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
index 2a17fed52f..f42df3dba2 100644
--- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
+++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
@@ -22,6 +22,12 @@ xenPVHMain:
;
xor esp, esp
+ ;
+ ; Store "Start of day" struct pointer for later use
+ ;
+ mov dword[PVH_SPACE (0)], ebx
+ mov dword[PVH_SPACE (4)], 'XPVH'
+
mov ebx, ADDR_OF(gdtr)
lgdt [ebx]
diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
index 0dbc4f2c1d..b2cb405d54 100644
--- a/OvmfPkg/XenResetVector/XenResetVector.nasmb
+++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
@@ -34,6 +34,8 @@
%include "CommonMacros.inc"
+%define PVH_SPACE(Offset) (FixedPcdGet32 (PcdXenPvhStartOfDayStructPtr) + (Offset))
+
%include "PostCodes.inc"
%ifdef DEBUG_PORT80
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 07/35] OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests
2019-07-04 14:42 ` [PATCH v3 07/35] OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests Anthony PERARD
@ 2019-07-05 14:24 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 14:24 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> As described in the Xen PVH documentation [1], "ebx: contains the
> physical memory address where the loader has placed the boot start info
> structure". To have this pointer saved to be able to use it later in the
> PEI phase, we allocate some space in the MEMFD for it. We use 'XPVH' as
> a signature (for "Xen PVH").
>
> [1] https://xenbits.xenproject.org/docs/unstable/misc/pvh.html
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
>
> Notes:
> v3:
> - rename PcdXenStartOfDay* to PcdXenPvhStartOfDay*
> - Use first available token value for those (0x17 and 0x28)
You ended up using 0x32 rather than 0x28, but that was necessary (and
correct) due to other patches meanwhile.
Also there's been a minimal comment style fix in "XenPVHMain.asm".
My Acked-by stands.
Thanks!
Laszlo
>
> OvmfPkg/OvmfPkg.dec | 3 +++
> OvmfPkg/OvmfXen.fdf | 4 ++++
> OvmfPkg/XenResetVector/XenResetVector.inf | 3 +++
> OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 6 ++++++
> OvmfPkg/XenResetVector/XenResetVector.nasmb | 2 ++
> 5 files changed, 18 insertions(+)
>
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 9640360f62..c2a2ebfb95 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -218,6 +218,9 @@ [PcdsFixedAtBuild]
> # The value should be a multiple of 4KB.
> gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize|0x400000|UINT32|0x31
>
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr|0x0|UINT32|0x17
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize|0x0|UINT32|0x32
> +
> [PcdsDynamic, PcdsDynamicEx]
> gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
> diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
> index 43c268f6cb..49997fee9b 100644
> --- a/OvmfPkg/OvmfXen.fdf
> +++ b/OvmfPkg/OvmfXen.fdf
> @@ -172,6 +172,10 @@ [FD.MEMFD]
> 0x007000|0x001000
> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>
> +0x008000|0x001000
> +# Used by XenResetVector to communicate with XenPlatformPei
> +gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr|gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
> +
> 0x010000|0x010000
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>
> diff --git a/OvmfPkg/XenResetVector/XenResetVector.inf b/OvmfPkg/XenResetVector/XenResetVector.inf
> index 097fc9b5b4..46b133a834 100644
> --- a/OvmfPkg/XenResetVector/XenResetVector.inf
> +++ b/OvmfPkg/XenResetVector/XenResetVector.inf
> @@ -36,3 +36,6 @@ [BuildOptions]
> [Pcd]
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> index 2a17fed52f..f42df3dba2 100644
> --- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -22,6 +22,12 @@ xenPVHMain:
> ;
> xor esp, esp
>
> + ;
> + ; Store "Start of day" struct pointer for later use
> + ;
> + mov dword[PVH_SPACE (0)], ebx
> + mov dword[PVH_SPACE (4)], 'XPVH'
> +
> mov ebx, ADDR_OF(gdtr)
> lgdt [ebx]
>
> diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> index 0dbc4f2c1d..b2cb405d54 100644
> --- a/OvmfPkg/XenResetVector/XenResetVector.nasmb
> +++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> @@ -34,6 +34,8 @@
>
> %include "CommonMacros.inc"
>
> +%define PVH_SPACE(Offset) (FixedPcdGet32 (PcdXenPvhStartOfDayStructPtr) + (Offset))
> +
> %include "PostCodes.inc"
>
> %ifdef DEBUG_PORT80
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (6 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 07/35] OvmfPkg/XenResetVector: Saving start of day pointer for PVH guests Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 14:54 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU Anthony PERARD
` (29 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
This patch allows the ResetVector to be run indenpendently from build
time addresses.
The goal of the patch is to avoid having to create RAM just below 4G
when creating a Xen PVH guest while being compatible with the way
hvmloader currently load OVMF, just below 4G.
Only the new PVH entry point will do the calculation.
The ResetVector will figure out its current running address by creating
a temporary stack, make a call and calculate the difference between the
build time address and the address at run time.
This patch copies and make the necessary modification to some other asm
files:
- copy of UefiCpuPkg/.../Flat32ToFlat64.asm:
Allow Transition32FlatTo64Flat to be run from anywhere in memory
- copy of UefiCpuPkg/../SearchForBfvBase.asm:
Add a extra parameter to indicate where to start the search for the
boot firmware volume.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- rebased, SPDX
- fix commit message
.../XenResetVector/Ia16/Real16ToFlat32.asm | 3 +
.../XenResetVector/Ia32/Flat32ToFlat64.asm | 68 +++++++++++++++
.../XenResetVector/Ia32/SearchForBfvBase.asm | 87 +++++++++++++++++++
OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 43 +++++++--
4 files changed, 194 insertions(+), 7 deletions(-)
create mode 100644 OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
create mode 100644 OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
index 5c329bfaea..36ea74f7fe 100644
--- a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
+++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
@@ -54,6 +54,9 @@ jumpTo32BitAndLandHere:
mov gs, ax
mov ss, ax
+ ; parameter for Flat32SearchForBfvBase
+ xor eax, eax ; Start searching from top of 4GB for BfvBase
+
OneTimeCallRet TransitionFromReal16To32BitFlat
ALIGN 2
diff --git a/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
new file mode 100644
index 0000000000..661a8e7028
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------
+; @file
+; Transition from 32 bit flat protected mode into 64 bit flat protected mode
+;
+; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 32
+
+;
+; Modified: EAX, EBX, ECX, EDX, ESP
+;
+Transition32FlatTo64Flat:
+
+ OneTimeCall SetCr3ForPageTables64
+
+ mov eax, cr4
+ bts eax, 5 ; enable PAE
+ mov cr4, eax
+
+ mov ecx, 0xc0000080
+ rdmsr
+ bts eax, 8 ; set LME
+ wrmsr
+
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax ; enable paging
+
+ ;
+ ; backup ESP
+ ;
+ mov ebx, esp
+
+ ;
+ ; recalculate delta
+ ;
+ mov esp, PVH_SPACE(16)
+ call .delta
+.delta:
+ pop edx
+ sub edx, ADDR_OF(.delta)
+
+ ;
+ ; push return addr and seg to the stack, then return far
+ ;
+ push dword LINEAR_CODE64_SEL
+ mov eax, ADDR_OF(jumpTo64BitAndLandHere)
+ add eax, edx ; add delta
+ push eax
+ retf
+
+BITS 64
+jumpTo64BitAndLandHere:
+
+ ;
+ ; restore ESP
+ ;
+ mov esp, ebx
+
+ debugShowPostCode POSTCODE_64BIT_MODE
+
+ OneTimeCallRet Transition32FlatTo64Flat
+
diff --git a/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
new file mode 100644
index 0000000000..190389c46f
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
@@ -0,0 +1,87 @@
+;------------------------------------------------------------------------------
+; @file
+; Search for the Boot Firmware Volume (BFV) base address
+;
+; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+;#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
+; { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }
+%define FFS_GUID_DWORD0 0x8c8ce578
+%define FFS_GUID_DWORD1 0x4f1c8a3d
+%define FFS_GUID_DWORD2 0x61893599
+%define FFS_GUID_DWORD3 0xd32dc385
+
+BITS 32
+
+;
+; Modified: EAX, EBX, ECX
+; Preserved: EDI, ESP
+;
+; @param[in] EAX Start search from here
+; @param[out] EBP Address of Boot Firmware Volume (BFV)
+;
+Flat32SearchForBfvBase:
+
+ mov ecx, eax
+searchingForBfvHeaderLoop:
+ ;
+ ; We check for a firmware volume at every 4KB address in the 16MB
+ ; just below where we started, ECX.
+ ;
+ sub eax, 0x1000
+ mov ebx, ecx
+ sub ebx, eax
+ cmp ebx, 0x01000000
+ ; if ECX-EAX > 16MB; jump notfound
+ ja searchedForBfvHeaderButNotFound
+
+ ;
+ ; Check FFS GUID
+ ;
+ cmp dword [eax + 0x10], FFS_GUID_DWORD0
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x14], FFS_GUID_DWORD1
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x18], FFS_GUID_DWORD2
+ jne searchingForBfvHeaderLoop
+ cmp dword [eax + 0x1c], FFS_GUID_DWORD3
+ jne searchingForBfvHeaderLoop
+
+ ;
+ ; Check FV Length
+ ;
+ cmp dword [eax + 0x24], 0
+ jne searchingForBfvHeaderLoop
+ mov ebx, eax
+ add ebx, dword [eax + 0x20]
+ cmp ebx, ecx
+ jnz searchingForBfvHeaderLoop
+
+ jmp searchedForBfvHeaderAndItWasFound
+
+searchedForBfvHeaderButNotFound:
+ ;
+ ; Hang if the SEC entry point was not found
+ ;
+ debugShowPostCode POSTCODE_BFV_NOT_FOUND
+
+ ;
+ ; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
+ ; for debugging purposes.
+ ;
+ mov eax, 0xBFBFBFBF
+ mov ebp, eax
+ jmp $
+
+searchedForBfvHeaderAndItWasFound:
+ mov ebp, eax
+
+ debugShowPostCode POSTCODE_BFV_FOUND
+
+ OneTimeCallRet Flat32SearchForBfvBase
+
diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
index f42df3dba2..2df0f12e18 100644
--- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
+++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
@@ -16,25 +16,42 @@ xenPVHMain:
;
mov di, 'BP'
- ;
- ; ESP will be used as initial value of the EAX register
- ; in Main.asm
- ;
- xor esp, esp
-
;
; Store "Start of day" struct pointer for later use
;
mov dword[PVH_SPACE (0)], ebx
mov dword[PVH_SPACE (4)], 'XPVH'
+ ;
+ ; calculate delta between build-addr and run position
+ ;
+ mov esp, PVH_SPACE(16) ; create a temporary stack
+ call .delta
+.delta:
+ pop edx ; get addr of .delta
+ sub edx, ADDR_OF(.delta) ; calculate delta
+
+ ;
+ ; Find address of GDT and gdtr and fix the later
+ ;
mov ebx, ADDR_OF(gdtr)
+ add ebx, edx ; add delta gdtr
+ mov eax, ADDR_OF(GDT_BASE)
+ add eax, edx ; add delta to GDT_BASE
+ mov dword[ebx + 2], eax ; fix GDT_BASE addr in gdtr
lgdt [ebx]
mov eax, SEC_DEFAULT_CR0
mov cr0, eax
- jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
+ ;
+ ; push return addr to the stack, then return far
+ ;
+ push dword LINEAR_CODE_SEL ; segment to select
+ mov eax, ADDR_OF(.jmpToNewCodeSeg) ; return addr
+ add eax, edx ; add delta to return addr
+ push eax
+ retf
.jmpToNewCodeSeg:
mov eax, SEC_DEFAULT_CR4
@@ -47,6 +64,18 @@ xenPVHMain:
mov gs, ax
mov ss, ax
+ ;
+ ; ESP will be used as initial value of the EAX register
+ ; in Main.asm
+ ;
+ xor esp, esp
+
+ ;
+ ; parameter for Flat32SearchForBfvBase
+ ;
+ mov eax, ADDR_OF(fourGigabytes)
+ add eax, edx ; add delta
+
;
; Jump to the main routine of the pre-SEC code
; skiping the 16-bit part of the routine and
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH
2019-07-04 14:42 ` [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH Anthony PERARD
@ 2019-07-05 14:54 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 14:54 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> This patch allows the ResetVector to be run indenpendently from build
> time addresses.
>
> The goal of the patch is to avoid having to create RAM just below 4G
> when creating a Xen PVH guest while being compatible with the way
> hvmloader currently load OVMF, just below 4G.
>
> Only the new PVH entry point will do the calculation.
>
> The ResetVector will figure out its current running address by creating
> a temporary stack, make a call and calculate the difference between the
> build time address and the address at run time.
>
> This patch copies and make the necessary modification to some other asm
> files:
> - copy of UefiCpuPkg/.../Flat32ToFlat64.asm:
> Allow Transition32FlatTo64Flat to be run from anywhere in memory
> - copy of UefiCpuPkg/../SearchForBfvBase.asm:
> Add a extra parameter to indicate where to start the search for the
> boot firmware volume.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
>
> Notes:
> v3:
> - rebased, SPDX
> - fix commit message
There are more changes in v3 than that.
First, some comment updates -- OK.
Second (and actually this goes back to another unlisted v3 change,
namely on patch#6 first):
- in v2:
- in patch #6, you store EAX to ESP at the top of xenPVHMain
- in patch #8, you stash EAX in EBP at the top of xenPVHMain, then
store EBP to ESP at the end of xenPVHMain
- in v3:
- in patch #6, you zero ESP at the top of xenPVHMain
- in patch #8 (this patch), you move the zeroing to the end of
xenPVHMain
To the extent that I care :) , this looks OK to me -- and so my A-b
stands --, but this change could be relevant for xen-devel reviewers,
and should be pointed out.
Thanks
Laszlo
> .../XenResetVector/Ia16/Real16ToFlat32.asm | 3 +
> .../XenResetVector/Ia32/Flat32ToFlat64.asm | 68 +++++++++++++++
> .../XenResetVector/Ia32/SearchForBfvBase.asm | 87 +++++++++++++++++++
> OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 43 +++++++--
> 4 files changed, 194 insertions(+), 7 deletions(-)
> create mode 100644 OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> create mode 100644 OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
>
> diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> index 5c329bfaea..36ea74f7fe 100644
> --- a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> +++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> @@ -54,6 +54,9 @@ jumpTo32BitAndLandHere:
> mov gs, ax
> mov ss, ax
>
> + ; parameter for Flat32SearchForBfvBase
> + xor eax, eax ; Start searching from top of 4GB for BfvBase
> +
> OneTimeCallRet TransitionFromReal16To32BitFlat
>
> ALIGN 2
> diff --git a/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> new file mode 100644
> index 0000000000..661a8e7028
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> @@ -0,0 +1,68 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Transition from 32 bit flat protected mode into 64 bit flat protected mode
> +;
> +; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS 32
> +
> +;
> +; Modified: EAX, EBX, ECX, EDX, ESP
> +;
> +Transition32FlatTo64Flat:
> +
> + OneTimeCall SetCr3ForPageTables64
> +
> + mov eax, cr4
> + bts eax, 5 ; enable PAE
> + mov cr4, eax
> +
> + mov ecx, 0xc0000080
> + rdmsr
> + bts eax, 8 ; set LME
> + wrmsr
> +
> + mov eax, cr0
> + bts eax, 31 ; set PG
> + mov cr0, eax ; enable paging
> +
> + ;
> + ; backup ESP
> + ;
> + mov ebx, esp
> +
> + ;
> + ; recalculate delta
> + ;
> + mov esp, PVH_SPACE(16)
> + call .delta
> +.delta:
> + pop edx
> + sub edx, ADDR_OF(.delta)
> +
> + ;
> + ; push return addr and seg to the stack, then return far
> + ;
> + push dword LINEAR_CODE64_SEL
> + mov eax, ADDR_OF(jumpTo64BitAndLandHere)
> + add eax, edx ; add delta
> + push eax
> + retf
> +
> +BITS 64
> +jumpTo64BitAndLandHere:
> +
> + ;
> + ; restore ESP
> + ;
> + mov esp, ebx
> +
> + debugShowPostCode POSTCODE_64BIT_MODE
> +
> + OneTimeCallRet Transition32FlatTo64Flat
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> new file mode 100644
> index 0000000000..190389c46f
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> @@ -0,0 +1,87 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Search for the Boot Firmware Volume (BFV) base address
> +;
> +; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +;#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
> +; { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }
> +%define FFS_GUID_DWORD0 0x8c8ce578
> +%define FFS_GUID_DWORD1 0x4f1c8a3d
> +%define FFS_GUID_DWORD2 0x61893599
> +%define FFS_GUID_DWORD3 0xd32dc385
> +
> +BITS 32
> +
> +;
> +; Modified: EAX, EBX, ECX
> +; Preserved: EDI, ESP
> +;
> +; @param[in] EAX Start search from here
> +; @param[out] EBP Address of Boot Firmware Volume (BFV)
> +;
> +Flat32SearchForBfvBase:
> +
> + mov ecx, eax
> +searchingForBfvHeaderLoop:
> + ;
> + ; We check for a firmware volume at every 4KB address in the 16MB
> + ; just below where we started, ECX.
> + ;
> + sub eax, 0x1000
> + mov ebx, ecx
> + sub ebx, eax
> + cmp ebx, 0x01000000
> + ; if ECX-EAX > 16MB; jump notfound
> + ja searchedForBfvHeaderButNotFound
> +
> + ;
> + ; Check FFS GUID
> + ;
> + cmp dword [eax + 0x10], FFS_GUID_DWORD0
> + jne searchingForBfvHeaderLoop
> + cmp dword [eax + 0x14], FFS_GUID_DWORD1
> + jne searchingForBfvHeaderLoop
> + cmp dword [eax + 0x18], FFS_GUID_DWORD2
> + jne searchingForBfvHeaderLoop
> + cmp dword [eax + 0x1c], FFS_GUID_DWORD3
> + jne searchingForBfvHeaderLoop
> +
> + ;
> + ; Check FV Length
> + ;
> + cmp dword [eax + 0x24], 0
> + jne searchingForBfvHeaderLoop
> + mov ebx, eax
> + add ebx, dword [eax + 0x20]
> + cmp ebx, ecx
> + jnz searchingForBfvHeaderLoop
> +
> + jmp searchedForBfvHeaderAndItWasFound
> +
> +searchedForBfvHeaderButNotFound:
> + ;
> + ; Hang if the SEC entry point was not found
> + ;
> + debugShowPostCode POSTCODE_BFV_NOT_FOUND
> +
> + ;
> + ; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
> + ; for debugging purposes.
> + ;
> + mov eax, 0xBFBFBFBF
> + mov ebp, eax
> + jmp $
> +
> +searchedForBfvHeaderAndItWasFound:
> + mov ebp, eax
> +
> + debugShowPostCode POSTCODE_BFV_FOUND
> +
> + OneTimeCallRet Flat32SearchForBfvBase
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> index f42df3dba2..2df0f12e18 100644
> --- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -16,25 +16,42 @@ xenPVHMain:
> ;
> mov di, 'BP'
>
> - ;
> - ; ESP will be used as initial value of the EAX register
> - ; in Main.asm
> - ;
> - xor esp, esp
> -
> ;
> ; Store "Start of day" struct pointer for later use
> ;
> mov dword[PVH_SPACE (0)], ebx
> mov dword[PVH_SPACE (4)], 'XPVH'
>
> + ;
> + ; calculate delta between build-addr and run position
> + ;
> + mov esp, PVH_SPACE(16) ; create a temporary stack
> + call .delta
> +.delta:
> + pop edx ; get addr of .delta
> + sub edx, ADDR_OF(.delta) ; calculate delta
> +
> + ;
> + ; Find address of GDT and gdtr and fix the later
> + ;
> mov ebx, ADDR_OF(gdtr)
> + add ebx, edx ; add delta gdtr
> + mov eax, ADDR_OF(GDT_BASE)
> + add eax, edx ; add delta to GDT_BASE
> + mov dword[ebx + 2], eax ; fix GDT_BASE addr in gdtr
> lgdt [ebx]
>
> mov eax, SEC_DEFAULT_CR0
> mov cr0, eax
>
> - jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
> + ;
> + ; push return addr to the stack, then return far
> + ;
> + push dword LINEAR_CODE_SEL ; segment to select
> + mov eax, ADDR_OF(.jmpToNewCodeSeg) ; return addr
> + add eax, edx ; add delta to return addr
> + push eax
> + retf
> .jmpToNewCodeSeg:
>
> mov eax, SEC_DEFAULT_CR4
> @@ -47,6 +64,18 @@ xenPVHMain:
> mov gs, ax
> mov ss, ax
>
> + ;
> + ; ESP will be used as initial value of the EAX register
> + ; in Main.asm
> + ;
> + xor esp, esp
> +
> + ;
> + ; parameter for Flat32SearchForBfvBase
> + ;
> + mov eax, ADDR_OF(fourGigabytes)
> + add eax, edx ; add delta
> +
> ;
> ; Jump to the main routine of the pre-SEC code
> ; skiping the 16-bit part of the routine and
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (7 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 15:01 ` Laszlo Ersek
2019-07-15 14:22 ` Roger Pau Monné
2019-07-04 14:42 ` [PATCH v3 10/35] OvmfPkg/XenPlatformPei: Detect OVMF_INFO from hvmloader Anthony PERARD
` (28 subsequent siblings)
37 siblings, 2 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD, Andrew Cooper, Roger Pau Monné
ACPI Timer does not work in a PVH guest, but local APIC works on both
PVH and HVM.
Note that the use of SecPeiDxeTimerLibCpu might be an issue with a
driver of type DXE_RUNTIME_DRIVER. I've attemptde to find out which of
the DXE_RUNTIME_DRIVER uses the TimerLib at runtime. I've done that by
replacing the TimerLib evaluation in
[LibraryClasses.common.DXE_RUNTIME_DRIVER] by a different one and
check every module that uses it (with the --report-file=report build
option).
ResetSystemRuntimeDxe is calling the TimerLib API at runtime to do the
operation "EfiResetCold", so this may never complete if the OS have
disabled the Local APIC Timer.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- cleanup .dsc, leave only one TimerLib resolution
- Added a note in the commit message regarding the use of the local apic
by runtime drivers
OvmfPkg/OvmfXen.dsc | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 9f79d455fa..6288394eb8 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -104,7 +104,7 @@ [SkuIds]
################################################################################
[LibraryClasses]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
- TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+ TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -202,7 +202,6 @@ [LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
[LibraryClasses.common.SEC]
- TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
!ifdef $(DEBUG_ON_SERIAL_PORT)
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
@@ -281,7 +280,6 @@ [LibraryClasses.common.DXE_CORE]
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -298,7 +296,6 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
[LibraryClasses.common.UEFI_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -313,7 +310,6 @@ [LibraryClasses.common.UEFI_DRIVER]
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -337,7 +333,6 @@ [LibraryClasses.common.DXE_DRIVER]
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-04 14:42 ` [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU Anthony PERARD
@ 2019-07-05 15:01 ` Laszlo Ersek
2019-07-15 14:22 ` Roger Pau Monné
1 sibling, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 15:01 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On 07/04/19 16:42, Anthony PERARD wrote:
> ACPI Timer does not work in a PVH guest, but local APIC works on both
> PVH and HVM.
>
> Note that the use of SecPeiDxeTimerLibCpu might be an issue with a
> driver of type DXE_RUNTIME_DRIVER. I've attemptde to find out which of
> the DXE_RUNTIME_DRIVER uses the TimerLib at runtime. I've done that by
> replacing the TimerLib evaluation in
> [LibraryClasses.common.DXE_RUNTIME_DRIVER] by a different one and
> check every module that uses it (with the --report-file=report build
> option).
>
> ResetSystemRuntimeDxe is calling the TimerLib API at runtime to do the
> operation "EfiResetCold", so this may never complete if the OS have
> disabled the Local APIC Timer.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - cleanup .dsc, leave only one TimerLib resolution
> - Added a note in the commit message regarding the use of the local apic
> by runtime drivers
Good note -- yes, the warning in
"MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf" applies.
I guess Xen setups can live with that potential problem, for now.
Acked-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
>
> OvmfPkg/OvmfXen.dsc | 7 +------
> 1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> index 9f79d455fa..6288394eb8 100644
> --- a/OvmfPkg/OvmfXen.dsc
> +++ b/OvmfPkg/OvmfXen.dsc
> @@ -104,7 +104,7 @@ [SkuIds]
> ################################################################################
> [LibraryClasses]
> PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
> + TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
> PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
> BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> @@ -202,7 +202,6 @@ [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>
> [LibraryClasses.common.SEC]
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
> !ifdef $(DEBUG_ON_SERIAL_PORT)
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> @@ -281,7 +280,6 @@ [LibraryClasses.common.DXE_CORE]
>
> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> @@ -298,7 +296,6 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>
> [LibraryClasses.common.UEFI_DRIVER]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> @@ -313,7 +310,6 @@ [LibraryClasses.common.UEFI_DRIVER]
>
> [LibraryClasses.common.DXE_DRIVER]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> @@ -337,7 +333,6 @@ [LibraryClasses.common.DXE_DRIVER]
>
> [LibraryClasses.common.UEFI_APPLICATION]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> - TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-04 14:42 ` [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU Anthony PERARD
2019-07-05 15:01 ` Laszlo Ersek
@ 2019-07-15 14:22 ` Roger Pau Monné
2019-07-22 13:49 ` Anthony PERARD
1 sibling, 1 reply; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-15 14:22 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Thu, Jul 04, 2019 at 03:42:07PM +0100, Anthony PERARD wrote:
> ACPI Timer does not work in a PVH guest, but local APIC works on both
This is not accurate. It's not that the ACPI timer doesn't work, it's
just that it's not present. The PM_TMR_BLK should be set to 0 to
indicate the lack of PM timer support, or else there's something
broken.
> PVH and HVM.
>
> Note that the use of SecPeiDxeTimerLibCpu might be an issue with a
> driver of type DXE_RUNTIME_DRIVER. I've attemptde to find out which of
^ attempted
> the DXE_RUNTIME_DRIVER uses the TimerLib at runtime. I've done that by
> replacing the TimerLib evaluation in
> [LibraryClasses.common.DXE_RUNTIME_DRIVER] by a different one and
> check every module that uses it (with the --report-file=report build
^ checking
> option).
>
> ResetSystemRuntimeDxe is calling the TimerLib API at runtime to do the
> operation "EfiResetCold", so this may never complete if the OS have
> disabled the Local APIC Timer.
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-15 14:22 ` Roger Pau Monné
@ 2019-07-22 13:49 ` Anthony PERARD
2019-07-22 19:28 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-22 13:49 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Mon, Jul 15, 2019 at 04:22:19PM +0200, Roger Pau Monné wrote:
> On Thu, Jul 04, 2019 at 03:42:07PM +0100, Anthony PERARD wrote:
> > ACPI Timer does not work in a PVH guest, but local APIC works on both
>
> This is not accurate. It's not that the ACPI timer doesn't work, it's
> just that it's not present. The PM_TMR_BLK should be set to 0 to
> indicate the lack of PM timer support, or else there's something
> broken.
I'll reword that first sentence.
OVMF doesn't look at the PM_TMR_BLK value when initializing that timer,
it only looks at the PCI host bridge device ID because OVMF is built
with QEMU in mind and there are only two possibles choices, QEMU is
running with a piix or q35 machine type, I think.
> > PVH and HVM.
> >
> > Note that the use of SecPeiDxeTimerLibCpu might be an issue with a
> > driver of type DXE_RUNTIME_DRIVER. I've attemptde to find out which of
> ^ attempted
> > the DXE_RUNTIME_DRIVER uses the TimerLib at runtime. I've done that by
> > replacing the TimerLib evaluation in
> > [LibraryClasses.common.DXE_RUNTIME_DRIVER] by a different one and
> > check every module that uses it (with the --report-file=report build
> ^ checking
> > option).
> >
> > ResetSystemRuntimeDxe is calling the TimerLib API at runtime to do the
> > operation "EfiResetCold", so this may never complete if the OS have
> > disabled the Local APIC Timer.
>
> Thanks, Roger.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-22 13:49 ` Anthony PERARD
@ 2019-07-22 19:28 ` Laszlo Ersek
2019-07-23 9:02 ` Roger Pau Monné
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-22 19:28 UTC (permalink / raw)
To: Anthony PERARD, Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper
On 07/22/19 15:49, Anthony PERARD wrote:
> On Mon, Jul 15, 2019 at 04:22:19PM +0200, Roger Pau Monné wrote:
>> On Thu, Jul 04, 2019 at 03:42:07PM +0100, Anthony PERARD wrote:
>>> ACPI Timer does not work in a PVH guest, but local APIC works on both
>>
>> This is not accurate. It's not that the ACPI timer doesn't work, it's
>> just that it's not present. The PM_TMR_BLK should be set to 0 to
>> indicate the lack of PM timer support, or else there's something
>> broken.
>
> I'll reword that first sentence.
>
> OVMF doesn't look at the PM_TMR_BLK value when initializing that timer,
> it only looks at the PCI host bridge device ID because OVMF is built
> with QEMU in mind and there are only two possibles choices, QEMU is
> running with a piix or q35 machine type, I think.
We should split this statement in two. :)
OVMF doesn't look at ACPI payload because it is a design goal to keep
the guest firmware un-enlightened about such ACPI contents that arrive
from the hypervisor. Parsing ACPI in firmware always looks attractive
until someone actually writes the code, and then it always ends in
misery -- at the latest when people realize they have to parse AML.
Parsing ACPI is only feasible when you have a full-blown ACPICA (or
similar) subsystem, and edk2 doesn't. Therefore, OVMF looks at either
hardware, or specialized paravirt information channels such as fw_cfg
files, that are easy to parse by design.
Second, within the above design guidelines (i.e. "don't try to parse
ACPI", and "cook your paravirt info if you want the firmware to eat
it"), OVMF looks at such artifacts to steer its behavior for which
patches have been submitted & merged. OVMF is integrated with Xen to the
extent of patches merged from the Xen community. Thus, in my opinion,
"OVMF is built with QEMU in mind" is a stretch -- perhaps it is so in
*my* mind personally, but that's just me. We have designated reviewers
for Xen-related code, and this series certainly builds OVMF with Xen in
mind. :)
If we reworded the statement, e.g. as "the present code targets QEMU and
is unsuitable when running on Xen", then I would not object.
Thanks!
Laszlo
>>> PVH and HVM.
>>>
>>> Note that the use of SecPeiDxeTimerLibCpu might be an issue with a
>>> driver of type DXE_RUNTIME_DRIVER. I've attemptde to find out which of
>> ^ attempted
>>> the DXE_RUNTIME_DRIVER uses the TimerLib at runtime. I've done that by
>>> replacing the TimerLib evaluation in
>>> [LibraryClasses.common.DXE_RUNTIME_DRIVER] by a different one and
>>> check every module that uses it (with the --report-file=report build
>> ^ checking
>>> option).
>>>
>>> ResetSystemRuntimeDxe is calling the TimerLib API at runtime to do the
>>> operation "EfiResetCold", so this may never complete if the OS have
>>> disabled the Local APIC Timer.
>>
>> Thanks, Roger.
>
> Thanks,
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU
2019-07-22 19:28 ` Laszlo Ersek
@ 2019-07-23 9:02 ` Roger Pau Monné
0 siblings, 0 replies; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-23 9:02 UTC (permalink / raw)
To: Laszlo Ersek
Cc: Anthony PERARD, devel, xen-devel, Ard Biesheuvel, Jordan Justen,
Julien Grall, Andrew Cooper
On Mon, Jul 22, 2019 at 09:28:20PM +0200, Laszlo Ersek wrote:
> On 07/22/19 15:49, Anthony PERARD wrote:
> > On Mon, Jul 15, 2019 at 04:22:19PM +0200, Roger Pau Monné wrote:
> >> On Thu, Jul 04, 2019 at 03:42:07PM +0100, Anthony PERARD wrote:
> >>> ACPI Timer does not work in a PVH guest, but local APIC works on both
> >>
> >> This is not accurate. It's not that the ACPI timer doesn't work, it's
> >> just that it's not present. The PM_TMR_BLK should be set to 0 to
> >> indicate the lack of PM timer support, or else there's something
> >> broken.
> >
> > I'll reword that first sentence.
> >
> > OVMF doesn't look at the PM_TMR_BLK value when initializing that timer,
> > it only looks at the PCI host bridge device ID because OVMF is built
> > with QEMU in mind and there are only two possibles choices, QEMU is
> > running with a piix or q35 machine type, I think.
>
> We should split this statement in two. :)
>
> OVMF doesn't look at ACPI payload because it is a design goal to keep
> the guest firmware un-enlightened about such ACPI contents that arrive
> from the hypervisor. Parsing ACPI in firmware always looks attractive
> until someone actually writes the code, and then it always ends in
> misery -- at the latest when people realize they have to parse AML.
> Parsing ACPI is only feasible when you have a full-blown ACPICA (or
> similar) subsystem, and edk2 doesn't. Therefore, OVMF looks at either
> hardware, or specialized paravirt information channels such as fw_cfg
> files, that are easy to parse by design.
IMO passing information using such side-channels always looks
attractive at first sight, until you realize at some point later that
you just have ended up with a completely custom interface that
duplicates ACPI. Having that said, Xen manages to get most of what it
needs from static ACPI tables, but I'm not sure if OVMF could manage
to do so also.
Xen has quite a lot of baggage here, like using xenstore/xenbus
instead of PCI, or custom 'start info pages' instead of ACPI, which we
are currently trying to partially move away from when possible.
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 10/35] OvmfPkg/XenPlatformPei: Detect OVMF_INFO from hvmloader
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (8 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 09/35] OvmfPkg/OvmfXen: use a TimerLib instance that depends only on the CPU Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 11/35] OvmfPkg/XenPlatformPei: Use mXenHvmloaderInfo to get E820 Anthony PERARD
` (27 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
EFI_XEN_OVMF_INFO is only useful to retrieve the E820 table. The
mXenHvmloaderInfo isn't used yet, but will be use in a further patch to
retrieve the E820 table.
Also remove the unused pointer from the XenInfo HOB as that information
is only useful in the XenPlatformPei.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix coding style
- fix commit message
OvmfPkg/Include/Guid/XenInfo.h | 4 ----
OvmfPkg/PlatformPei/Xen.c | 3 ---
OvmfPkg/XenPlatformPei/Xen.c | 25 +++++++++++++++++++++++--
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h
index 25d76a7828..b052d618fd 100644
--- a/OvmfPkg/Include/Guid/XenInfo.h
+++ b/OvmfPkg/Include/Guid/XenInfo.h
@@ -18,10 +18,6 @@ typedef struct {
///
VOID *HyperPages;
///
- /// Location of the hvm_info page.
- ///
- VOID *HvmInfo;
- ///
/// Hypervisor major version.
///
UINT16 VersionMajor;
diff --git a/OvmfPkg/PlatformPei/Xen.c b/OvmfPkg/PlatformPei/Xen.c
index 89dc4143b2..3e15b32a73 100644
--- a/OvmfPkg/PlatformPei/Xen.c
+++ b/OvmfPkg/PlatformPei/Xen.c
@@ -98,9 +98,6 @@ XenConnect (
mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
- /* TBD: Locate hvm_info and reserve it away. */
- mXenInfo.HvmInfo = NULL;
-
BuildGuidDataHob (
&gEfiXenInfoGuid,
&mXenInfo,
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 81042ab94f..d6361da306 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -33,6 +33,12 @@ STATIC UINT32 mXenLeaf = 0;
EFI_XEN_INFO mXenInfo;
+//
+// Location of the firmware info struct setup by hvmloader.
+// Only the E820 table is used by OVMF.
+//
+EFI_XEN_OVMF_INFO *mXenHvmloaderInfo;
+
/**
Returns E820 map provided by Xen
@@ -78,6 +84,8 @@ XenConnect (
UINT32 TransferReg;
UINT32 TransferPages;
UINT32 XenVersion;
+ EFI_XEN_OVMF_INFO *Info;
+ CHAR8 Sig[sizeof (Info->Signature) + 1];
AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
mXenInfo.HyperPages = AllocatePages (TransferPages);
@@ -97,8 +105,21 @@ XenConnect (
mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
- /* TBD: Locate hvm_info and reserve it away. */
- mXenInfo.HvmInfo = NULL;
+ //
+ // Check if there are information left by hvmloader
+ //
+
+ Info = (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
+ //
+ // Copy the signature, and make it null-terminated.
+ //
+ AsciiStrnCpyS (Sig, sizeof (Sig), (CHAR8 *) &Info->Signature,
+ sizeof (Info->Signature));
+ if (AsciiStrCmp (Sig, "XenHVMOVMF") == 0) {
+ mXenHvmloaderInfo = Info;
+ } else {
+ mXenHvmloaderInfo = NULL;
+ }
BuildGuidDataHob (
&gEfiXenInfoGuid,
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 11/35] OvmfPkg/XenPlatformPei: Use mXenHvmloaderInfo to get E820
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (9 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 10/35] OvmfPkg/XenPlatformPei: Detect OVMF_INFO from hvmloader Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 12/35] OvmfPkg/XenPlatformPei: Grab RSDP from PVH guest start of day struct Anthony PERARD
` (26 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Use the already checked pointer mXenHvmloaderInfo to retrieve the E820
table produced by hvmloader.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
OvmfPkg/XenPlatformPei/Xen.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index d6361da306..9c2ff6324d 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -53,18 +53,18 @@ XenGetE820Map (
UINT32 *Count
)
{
- EFI_XEN_OVMF_INFO *Info =
- (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
+ //
+ // Get E820 produced by hvmloader
+ //
+ if (mXenHvmloaderInfo != NULL) {
+ ASSERT (mXenHvmloaderInfo->E820 < MAX_ADDRESS);
+ *Entries = (EFI_E820_ENTRY64 *)(UINTN) mXenHvmloaderInfo->E820;
+ *Count = mXenHvmloaderInfo->E820EntriesCount;
- if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {
- return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
}
- ASSERT (Info->E820 < MAX_ADDRESS);
- *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;
- *Count = Info->E820EntriesCount;
-
- return EFI_SUCCESS;
+ return EFI_NOT_FOUND;
}
/**
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 12/35] OvmfPkg/XenPlatformPei: Grab RSDP from PVH guest start of day struct
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (10 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 11/35] OvmfPkg/XenPlatformPei: Use mXenHvmloaderInfo to get E820 Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 13/35] OvmfPkg/Library/XenPlatformLib: New library Anthony PERARD
` (25 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Check if there's a start of the day struct provided to PVH guest, save
the ACPI RSDP address for later.
This patch import import arch-x86/hvm/start_info.h from xen.git.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- use SPDX
- use SIGNATURE_32
- fix coding style
OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 3 +
OvmfPkg/Include/Guid/XenInfo.h | 4 +
.../Xen/arch-x86/hvm/start_info.h | 143 ++++++++++++++++++
OvmfPkg/XenPlatformPei/Xen.c | 25 +++
4 files changed, 175 insertions(+)
create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
index d1265c365a..4d00206d09 100644
--- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
+++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
@@ -84,6 +84,9 @@ [Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr
+ gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
+
[FixedPcd]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h
index b052d618fd..25743b3884 100644
--- a/OvmfPkg/Include/Guid/XenInfo.h
+++ b/OvmfPkg/Include/Guid/XenInfo.h
@@ -25,6 +25,10 @@ typedef struct {
/// Hypervisor minor version.
///
UINT16 VersionMinor;
+ ///
+ /// Pointer to the RSDP found in the hvm_start_info provided to a PVH guest
+ ///
+ VOID *RsdpPvh;
} EFI_XEN_INFO;
extern EFI_GUID gEfiXenInfoGuid;
diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h
new file mode 100644
index 0000000000..15708d6dd5
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h
@@ -0,0 +1,143 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2016, Citrix Systems, Inc.
+ */
+
+#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__
+#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__
+
+/*
+ * Start of day structure passed to PVH guests and to HVM guests in %ebx.
+ *
+ * NOTE: nothing will be loaded at physical address 0, so a 0 value in any
+ * of the address fields should be treated as not present.
+ *
+ * 0 +----------------+
+ * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE
+ * | | ("xEn3" with the 0x80 bit of the "E" set).
+ * 4 +----------------+
+ * | version | Version of this structure. Current version is 1. New
+ * | | versions are guaranteed to be backwards-compatible.
+ * 8 +----------------+
+ * | flags | SIF_xxx flags.
+ * 12 +----------------+
+ * | nr_modules | Number of modules passed to the kernel.
+ * 16 +----------------+
+ * | modlist_paddr | Physical address of an array of modules
+ * | | (layout of the structure below).
+ * 24 +----------------+
+ * | cmdline_paddr | Physical address of the command line,
+ * | | a zero-terminated ASCII string.
+ * 32 +----------------+
+ * | rsdp_paddr | Physical address of the RSDP ACPI data structure.
+ * 40 +----------------+
+ * | memmap_paddr | Physical address of the (optional) memory map. Only
+ * | | present in version 1 and newer of the structure.
+ * 48 +----------------+
+ * | memmap_entries | Number of entries in the memory map table. Zero
+ * | | if there is no memory map being provided. Only
+ * | | present in version 1 and newer of the structure.
+ * 52 +----------------+
+ * | reserved | Version 1 and newer only.
+ * 56 +----------------+
+ *
+ * The layout of each entry in the module structure is the following:
+ *
+ * 0 +----------------+
+ * | paddr | Physical address of the module.
+ * 8 +----------------+
+ * | size | Size of the module in bytes.
+ * 16 +----------------+
+ * | cmdline_paddr | Physical address of the command line,
+ * | | a zero-terminated ASCII string.
+ * 24 +----------------+
+ * | reserved |
+ * 32 +----------------+
+ *
+ * The layout of each entry in the memory map table is as follows:
+ *
+ * 0 +----------------+
+ * | addr | Base address
+ * 8 +----------------+
+ * | size | Size of mapping in bytes
+ * 16 +----------------+
+ * | type | Type of mapping as defined between the hypervisor
+ * | | and guest. See XEN_HVM_MEMMAP_TYPE_* values below.
+ * 20 +----------------|
+ * | reserved |
+ * 24 +----------------+
+ *
+ * The address and sizes are always a 64bit little endian unsigned integer.
+ *
+ * NB: Xen on x86 will always try to place all the data below the 4GiB
+ * boundary.
+ *
+ * Version numbers of the hvm_start_info structure have evolved like this:
+ *
+ * Version 0: Initial implementation.
+ *
+ * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes of
+ * padding) to the end of the hvm_start_info struct. These new
+ * fields can be used to pass a memory map to the guest. The
+ * memory map is optional and so guests that understand version 1
+ * of the structure must check that memmap_entries is non-zero
+ * before trying to read the memory map.
+ */
+#define XEN_HVM_START_MAGIC_VALUE 0x336ec578
+
+/*
+ * The values used in the type field of the memory map table entries are
+ * defined below and match the Address Range Types as defined in the "System
+ * Address Map Interfaces" section of the ACPI Specification. Please refer to
+ * section 15 in version 6.2 of the ACPI spec: http://uefi.org/specifications
+ */
+#define XEN_HVM_MEMMAP_TYPE_RAM 1
+#define XEN_HVM_MEMMAP_TYPE_RESERVED 2
+#define XEN_HVM_MEMMAP_TYPE_ACPI 3
+#define XEN_HVM_MEMMAP_TYPE_NVS 4
+#define XEN_HVM_MEMMAP_TYPE_UNUSABLE 5
+#define XEN_HVM_MEMMAP_TYPE_DISABLED 6
+#define XEN_HVM_MEMMAP_TYPE_PMEM 7
+
+/*
+ * C representation of the x86/HVM start info layout.
+ *
+ * The canonical definition of this layout is above, this is just a way to
+ * represent the layout described there using C types.
+ */
+struct hvm_start_info {
+ UINT32 magic; /* Contains the magic value 0x336ec578 */
+ /* ("xEn3" with the 0x80 bit of the "E" set).*/
+ UINT32 version; /* Version of this structure. */
+ UINT32 flags; /* SIF_xxx flags. */
+ UINT32 nr_modules; /* Number of modules passed to the kernel. */
+ UINT64 modlist_paddr; /* Physical address of an array of */
+ /* hvm_modlist_entry. */
+ UINT64 cmdline_paddr; /* Physical address of the command line. */
+ UINT64 rsdp_paddr; /* Physical address of the RSDP ACPI data */
+ /* structure. */
+ /* All following fields only present in version 1 and newer */
+ UINT64 memmap_paddr; /* Physical address of an array of */
+ /* hvm_memmap_table_entry. */
+ UINT32 memmap_entries; /* Number of entries in the memmap table. */
+ /* Value will be zero if there is no memory */
+ /* map being provided. */
+ UINT32 reserved; /* Must be zero. */
+};
+
+struct hvm_modlist_entry {
+ UINT64 paddr; /* Physical address of the module. */
+ UINT64 size; /* Size of the module in bytes. */
+ UINT64 cmdline_paddr; /* Physical address of the command line. */
+ UINT64 reserved;
+};
+
+struct hvm_memmap_table_entry {
+ UINT64 addr; /* Base address of the memory region */
+ UINT64 size; /* Size of the memory region in bytes */
+ UINT32 type; /* Mapping type */
+ UINT32 reserved; /* Must be zero for Version 1. */
+};
+
+#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 9c2ff6324d..c5293498c4 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -25,6 +25,7 @@
#include <IndustryStandard/E820.h>
#include <Library/ResourcePublicationLib.h>
#include <Library/MtrrLib.h>
+#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
#include "Platform.h"
#include "Xen.h"
@@ -86,6 +87,7 @@ XenConnect (
UINT32 XenVersion;
EFI_XEN_OVMF_INFO *Info;
CHAR8 Sig[sizeof (Info->Signature) + 1];
+ UINT32 *PVHResetVectorData;
AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
mXenInfo.HyperPages = AllocatePages (TransferPages);
@@ -121,6 +123,29 @@ XenConnect (
mXenHvmloaderInfo = NULL;
}
+ mXenInfo.RsdpPvh = NULL;
+
+ //
+ // Locate and use information from the start of day structure if we have
+ // booted via the PVH entry point.
+ //
+
+ PVHResetVectorData = (VOID *)(UINTN) PcdGet32 (PcdXenPvhStartOfDayStructPtr);
+ //
+ // That magic value is written in XenResetVector/Ia32/XenPVHMain.asm
+ //
+ if (PVHResetVectorData[1] == SIGNATURE_32 ('X', 'P', 'V', 'H')) {
+ struct hvm_start_info *HVMStartInfo;
+
+ HVMStartInfo = (VOID *)(UINTN) PVHResetVectorData[0];
+ if (HVMStartInfo->magic == XEN_HVM_START_MAGIC_VALUE) {
+ ASSERT (HVMStartInfo->rsdp_paddr != 0);
+ if (HVMStartInfo->rsdp_paddr != 0) {
+ mXenInfo.RsdpPvh = (VOID *)(UINTN)HVMStartInfo->rsdp_paddr;
+ }
+ }
+ }
+
BuildGuidDataHob (
&gEfiXenInfoGuid,
&mXenInfo,
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 13/35] OvmfPkg/Library/XenPlatformLib: New library
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (11 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 12/35] OvmfPkg/XenPlatformPei: Grab RSDP from PVH guest start of day struct Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 14:34 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib Anthony PERARD
` (24 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
The purpose of XenPlatformLib is to regroup the few functions that are
used in several places to detect if Xen is detected, and to get the
XenInfo HOB.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- use SPDX
- add XenPlatformLib.h to [LibraryClasses] in OvmfPkg.dec
- fix typos
OvmfPkg/OvmfPkg.dec | 4 ++
OvmfPkg/OvmfXen.dsc | 1 +
.../Library/XenPlatformLib/XenPlatformLib.inf | 33 +++++++++
OvmfPkg/Include/Library/XenPlatformLib.h | 53 ++++++++++++++
.../Library/XenPlatformLib/XenPlatformLib.c | 69 +++++++++++++++++++
5 files changed, 160 insertions(+)
create mode 100644 OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
create mode 100644 OvmfPkg/Include/Library/XenPlatformLib.h
create mode 100644 OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index c2a2ebfb95..04d5e29272 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -70,6 +70,10 @@ [LibraryClasses]
#
XenIoMmioLib|Include/Library/XenIoMmioLib.h
+ ## @libraryclass Get information about Xen
+ #
+ XenPlatformLib|Include/Library/XenPlatformLib.h
+
[Guids]
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 6288394eb8..68d82da7aa 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -195,6 +195,7 @@ [LibraryClasses]
SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+ XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
diff --git a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
new file mode 100644
index 0000000000..32adb246d6
--- /dev/null
+++ b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Get information about Xen
+#
+# This library simply allow to find out if OVMF is running under Xen and
+# allow to get more information when it is the case.
+#
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = XenPlatformLib
+ FILE_GUID = DB54DBB7-8142-4EE5-9364-78C824B582EB
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = XenPlatformLib
+
+[Sources]
+ XenPlatformLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ HobLib
+
+[Guids]
+ gEfiXenInfoGuid
diff --git a/OvmfPkg/Include/Library/XenPlatformLib.h b/OvmfPkg/Include/Library/XenPlatformLib.h
new file mode 100644
index 0000000000..a8347602b7
--- /dev/null
+++ b/OvmfPkg/Include/Library/XenPlatformLib.h
@@ -0,0 +1,53 @@
+/** @file
+* Get information about Xen
+*
+* This library simply allow to find out if OVMF is running under Xen and
+* allow to get more information when it is the case.
+*
+* Copyright (c) 2019, Citrix Systems, Inc.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _XEN_PLATFORM_LIB_H_
+#define _XEN_PLATFORM_LIB_H_
+
+#include <Guid/XenInfo.h>
+
+/**
+ This function detects if OVMF is running on Xen.
+
+ @retval TRUE OVMF is running on Xen
+ @retval FALSE Xen has not been detected
+**/
+BOOLEAN
+EFIAPI
+XenDetected (
+ VOID
+ );
+
+/**
+ This function detect if OVMF have started via the PVH entry point.
+
+ @retval TRUE PVH entry point as been used
+ @retval FALSE OVMF have started via the HVM route
+**/
+BOOLEAN
+EFIAPI
+XenPvhDetected (
+ VOID
+ );
+
+/**
+ This function return a pointer to the XenInfo HOB.
+
+ @return XenInfo pointer or NULL if not available
+**/
+EFI_XEN_INFO *
+EFIAPI
+XenGetInfoHOB (
+ VOID
+ );
+
+#endif
diff --git a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
new file mode 100644
index 0000000000..6f27cbffa8
--- /dev/null
+++ b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
@@ -0,0 +1,69 @@
+/** @file
+* Get information about Xen
+*
+* This library simply allow to find out if OVMF is running under Xen and
+* allow to get more information when it is the case.
+*
+* Copyright (c) 2019, Citrix Systems, Inc.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+#include <Library/XenPlatformLib.h>
+
+/**
+ This function return a pointer to the XenInfo HOB.
+
+ @return XenInfo pointer or NULL if not available
+**/
+EFI_XEN_INFO *
+EFIAPI
+XenGetInfoHOB (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
+ if (GuidHob == NULL) {
+ return NULL;
+ }
+
+ return (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
+}
+
+/**
+ This function detects if OVMF is running on Xen.
+
+ @retval TRUE OVMF is running on Xen
+ @retval FALSE Xen has not been detected
+**/
+BOOLEAN
+EFIAPI
+XenDetected (
+ VOID
+ )
+{
+ return (XenGetInfoHOB () != NULL);
+}
+
+/**
+ This function detect if OVMF have started via the PVH entry point.
+
+ @retval TRUE PVH entry point as been used
+ @retval FALSE OVMF have started via the HVM route
+**/
+BOOLEAN
+EFIAPI
+XenPvhDetected (
+ VOID
+ )
+{
+ EFI_XEN_INFO *XenInfo;
+
+ XenInfo = XenGetInfoHOB ();
+ return (XenInfo != NULL && XenInfo->RsdpPvh != NULL);
+}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 13/35] OvmfPkg/Library/XenPlatformLib: New library
2019-07-04 14:42 ` [PATCH v3 13/35] OvmfPkg/Library/XenPlatformLib: New library Anthony PERARD
@ 2019-07-08 14:34 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 14:34 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> The purpose of XenPlatformLib is to regroup the few functions that are
> used in several places to detect if Xen is detected, and to get the
> XenInfo HOB.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - use SPDX
> - add XenPlatformLib.h to [LibraryClasses] in OvmfPkg.dec
> - fix typos
>
[snip]
> diff --git a/OvmfPkg/Include/Library/XenPlatformLib.h b/OvmfPkg/Include/Library/XenPlatformLib.h
> new file mode 100644
> index 0000000000..a8347602b7
> --- /dev/null
> +++ b/OvmfPkg/Include/Library/XenPlatformLib.h
> @@ -0,0 +1,53 @@
> +/** @file
> +* Get information about Xen
> +*
> +* This library simply allow to find out if OVMF is running under Xen and
> +* allow to get more information when it is the case.
> +*
> +* Copyright (c) 2019, Citrix Systems, Inc.
> +*
> +* SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
[snip]
> diff --git a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
> new file mode 100644
> index 0000000000..6f27cbffa8
> --- /dev/null
> +++ b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
> @@ -0,0 +1,69 @@
> +/** @file
> +* Get information about Xen
> +*
> +* This library simply allow to find out if OVMF is running under Xen and
> +* allow to get more information when it is the case.
> +*
> +* Copyright (c) 2019, Citrix Systems, Inc.
> +*
> +* SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
These comment blocks should not have a column of "*" to the left.
With that fixed:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (12 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 13/35] OvmfPkg/Library/XenPlatformLib: New library Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 14:38 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 15/35] OvmfPkg/AcpiPlatformDxe: Use Xen PVH RSDP if it exist Anthony PERARD
` (23 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
This patch replace the XenDetected() function by the one in
XenPlatformLib.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- new patch, splited from the next patch
(which was OvmfPkg/AcpiPlatformDxe: Use PVH RSDP if exist)
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 2 +-
OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h | 6 +-----
OvmfPkg/AcpiPlatformDxe/Xen.c | 24 ---------------------
6 files changed, 5 insertions(+), 30 deletions(-)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index d60bcd5e54..1b116fe3b3 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -202,6 +202,7 @@ [LibraryClasses]
SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+ XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index ded3e8a464..bd8625a075 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -207,6 +207,7 @@ [LibraryClasses]
SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+ XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 131f2b0b47..db9ba7cc15 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -207,6 +207,7 @@ [LibraryClasses]
SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+ XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
!if $(TPM2_ENABLE) == TRUE
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 24634eeae2..eadace366d 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -44,13 +44,13 @@ [LibraryClasses]
DebugLib
UefiBootServicesTableLib
UefiDriverEntryPoint
- HobLib
QemuFwCfgLib
QemuFwCfgS3Lib
MemoryAllocationLib
BaseLib
DxeServicesTableLib
OrderedCollectionLib
+ XenPlatformLib
[Protocols]
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
index 3037afcf18..9597e028e4 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
@@ -19,6 +19,7 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
+#include <Library/XenPlatformLib.h>
#include <IndustryStandard/Acpi.h>
@@ -52,11 +53,6 @@ QemuInstallAcpiTable (
OUT UINTN *TableKey
);
-BOOLEAN
-XenDetected (
- VOID
- );
-
EFI_STATUS
EFIAPI
InstallXenTables (
diff --git a/OvmfPkg/AcpiPlatformDxe/Xen.c b/OvmfPkg/AcpiPlatformDxe/Xen.c
index e4e47bf0e8..82794b933e 100644
--- a/OvmfPkg/AcpiPlatformDxe/Xen.c
+++ b/OvmfPkg/AcpiPlatformDxe/Xen.c
@@ -9,8 +9,6 @@
**/
#include "AcpiPlatform.h"
-#include <Library/HobLib.h>
-#include <Guid/XenInfo.h>
#include <Library/BaseLib.h>
#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020
@@ -18,28 +16,6 @@
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL;
-/**
- This function detects if OVMF is running on Xen.
-
-**/
-BOOLEAN
-XenDetected (
- VOID
- )
-{
- EFI_HOB_GUID_TYPE *GuidHob;
-
- //
- // See if a XenInfo HOB is available
- //
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
- if (GuidHob == NULL) {
- return FALSE;
- }
-
- return TRUE;
-}
-
/**
Get the address of Xen ACPI Root System Description Pointer (RSDP)
structure.
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib
2019-07-04 14:42 ` [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib Anthony PERARD
@ 2019-07-08 14:38 ` Laszlo Ersek
2019-07-10 9:42 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 14:38 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> This patch replace the XenDetected() function by the one in
> XenPlatformLib.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - new patch, splited from the next patch
> (which was OvmfPkg/AcpiPlatformDxe: Use PVH RSDP if exist)
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib
2019-07-08 14:38 ` Laszlo Ersek
@ 2019-07-10 9:42 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 9:42 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/08/19 16:38, Laszlo Ersek wrote:
> On 07/04/19 16:42, Anthony PERARD wrote:
>> This patch replace the XenDetected() function by the one in
>> XenPlatformLib.
>>
>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>> ---
>>
>> Notes:
>> v3:
>> - new patch, splited from the next patch
>> (which was OvmfPkg/AcpiPlatformDxe: Use PVH RSDP if exist)
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>
Sorry, I missed a cleanup option: please remove "gEfiXenInfoGuid" from
[Guids] in "AcpiPlatformDxe.inf".
(You can pick up the R-b with that.)
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 15/35] OvmfPkg/AcpiPlatformDxe: Use Xen PVH RSDP if it exist
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (13 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 14/35] OvmfPkg/AcpiPlatformDxe: Use XenPlatformLib Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 14:42 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 16/35] OvmfPkg/XenHypercallLib: Enable it in PEIM Anthony PERARD
` (22 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
If the firmware have been started via the Xen PVH entry point, a RSDP
pointer would have been provided. Use it.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- patch splited from the previous one
- Fix DEBUG format string, use %p for pointers.
and use gEfiCallerBaseName to print module name
OvmfPkg/AcpiPlatformDxe/Xen.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/OvmfPkg/AcpiPlatformDxe/Xen.c b/OvmfPkg/AcpiPlatformDxe/Xen.c
index 82794b933e..376a6bd3cb 100644
--- a/OvmfPkg/AcpiPlatformDxe/Xen.c
+++ b/OvmfPkg/AcpiPlatformDxe/Xen.c
@@ -36,10 +36,27 @@ GetXenAcpiRsdp (
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
UINT8 *XenAcpiPtr;
UINT8 Sum;
+ EFI_XEN_INFO *XenInfo;
//
// Detect the RSDP structure
//
+
+ //
+ // First look for PVH one
+ //
+ XenInfo = XenGetInfoHOB ();
+ ASSERT (XenInfo != NULL);
+ if (XenInfo->RsdpPvh != NULL) {
+ DEBUG ((DEBUG_INFO, "%a: Use ACPI RSDP table at 0x%p\n",
+ gEfiCallerBaseName, XenInfo->RsdpPvh));
+ *RsdpPtr = XenInfo->RsdpPvh;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Otherwise, look for the HVM one
+ //
for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;
XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;
XenAcpiPtr += 0x10) {
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 15/35] OvmfPkg/AcpiPlatformDxe: Use Xen PVH RSDP if it exist
2019-07-04 14:42 ` [PATCH v3 15/35] OvmfPkg/AcpiPlatformDxe: Use Xen PVH RSDP if it exist Anthony PERARD
@ 2019-07-08 14:42 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 14:42 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> If the firmware have been started via the Xen PVH entry point, a RSDP
> pointer would have been provided. Use it.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - patch splited from the previous one
> - Fix DEBUG format string, use %p for pointers.
> and use gEfiCallerBaseName to print module name
>
> OvmfPkg/AcpiPlatformDxe/Xen.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/OvmfPkg/AcpiPlatformDxe/Xen.c b/OvmfPkg/AcpiPlatformDxe/Xen.c
> index 82794b933e..376a6bd3cb 100644
> --- a/OvmfPkg/AcpiPlatformDxe/Xen.c
> +++ b/OvmfPkg/AcpiPlatformDxe/Xen.c
> @@ -36,10 +36,27 @@ GetXenAcpiRsdp (
> EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
> UINT8 *XenAcpiPtr;
> UINT8 Sum;
> + EFI_XEN_INFO *XenInfo;
>
> //
> // Detect the RSDP structure
> //
> +
> + //
> + // First look for PVH one
> + //
> + XenInfo = XenGetInfoHOB ();
> + ASSERT (XenInfo != NULL);
> + if (XenInfo->RsdpPvh != NULL) {
> + DEBUG ((DEBUG_INFO, "%a: Use ACPI RSDP table at 0x%p\n",
> + gEfiCallerBaseName, XenInfo->RsdpPvh));
(1) Please fix the indentation here; "gEfiCallerBaseName" should start
under the "B" in "DEBUG".
With that updated:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
> + *RsdpPtr = XenInfo->RsdpPvh;
> + return EFI_SUCCESS;
> + }
> +
> + //
> + // Otherwise, look for the HVM one
> + //
> for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;
> XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;
> XenAcpiPtr += 0x10) {
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 16/35] OvmfPkg/XenHypercallLib: Enable it in PEIM
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (14 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 15/35] OvmfPkg/AcpiPlatformDxe: Use Xen PVH RSDP if it exist Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 14:51 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 17/35] OvmfPkg/XenPlatformPei: Reinit XenHypercallLib Anthony PERARD
` (21 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Allow to use Xen hypercalls earlier, during the PEIM stage, but
XenHypercallLibInit() must be called once the XenInfo HOB is created
with the HyperPage setup.
Change the return value of XenHypercallLibInit so failure can be
detected when the call shouldn't fail, but still have the constructor
always succeed.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- only modify XenHypercallLib, and to the modification of XenPlatformPei
in a separated patch.
- Allow XenHypercallLibInit to be called outside the library instead of
creating a new function, but also return failure on failure,
and have a new constructor that never fail.
.../Library/XenHypercallLib/XenHypercallLib.inf | 4 ++--
OvmfPkg/Include/Library/XenHypercallLib.h | 12 ++++++++++++
.../Library/XenHypercallLib/X86XenHypercall.c | 8 +-------
OvmfPkg/Library/XenHypercallLib/XenHypercall.c | 16 ++++++++++++++++
4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
index 1208f0057a..21ce5b4434 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -12,10 +12,10 @@ [Defines]
FILE_GUID = B5EE9A32-CA5A-49A8-82E3-ADA4CCB77C7C
MODULE_TYPE = BASE
VERSION_STRING = 1.0
- CONSTRUCTOR = XenHypercallLibInit
+ CONSTRUCTOR = XenHypercallLibConstruct
[Defines.IA32, Defines.X64]
- LIBRARY_CLASS = XenHypercallLib|DXE_DRIVER UEFI_DRIVER
+ LIBRARY_CLASS = XenHypercallLib|PEIM DXE_DRIVER UEFI_DRIVER
[Defines.ARM, Defines.AARCH64]
LIBRARY_CLASS = XenHypercallLib
diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
index c43822782b..c1491dd652 100644
--- a/OvmfPkg/Include/Library/XenHypercallLib.h
+++ b/OvmfPkg/Include/Library/XenHypercallLib.h
@@ -10,6 +10,18 @@
#ifndef __XEN_HYPERCALL_LIB_H__
#define __XEN_HYPERCALL_LIB_H__
+/**
+ To call when the gEfiXenInfoGuid HOB became available after the library init
+ function has already been executed.
+
+ This allow to make hypercall in the PEIM stage.
+**/
+RETURN_STATUS
+EFIAPI
+XenHypercallLibInit (
+ VOID
+ );
+
/**
Check if the Xen Hypercall library is able to make calls to the Xen
hypervisor.
diff --git a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
index 27083f924f..f779e46470 100644
--- a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
@@ -59,13 +59,7 @@ XenHypercallLibInit (
GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
if (GuidHob == NULL) {
- //
- // We don't fail library construction, since that has catastrophic
- // consequences for client modules (whereas those modules may easily be
- // running on a non-Xen platform). Instead, XenHypercallIsAvailable() above
- // will return FALSE.
- //
- return RETURN_SUCCESS;
+ return RETURN_NOT_FOUND;
}
XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
HyperPage = XenInfo->HyperPages;
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
index a2c41a2a69..d4fa802743 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
@@ -15,6 +15,22 @@
#include <Library/DebugLib.h>
#include <Library/XenHypercallLib.h>
+RETURN_STATUS
+EFIAPI
+XenHypercallLibConstruct (
+ VOID
+ )
+{
+ XenHypercallLibInit ();
+ //
+ // We don't fail library construction, since that has catastrophic
+ // consequences for client modules (whereas those modules may easily be
+ // running on a non-Xen platform). Instead, XenHypercallIsAvailable()
+ // will return FALSE.
+ //
+ return RETURN_SUCCESS;
+}
+
UINT64
EFIAPI
XenHypercallHvmGetParam (
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 16/35] OvmfPkg/XenHypercallLib: Enable it in PEIM
2019-07-04 14:42 ` [PATCH v3 16/35] OvmfPkg/XenHypercallLib: Enable it in PEIM Anthony PERARD
@ 2019-07-08 14:51 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 14:51 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> Allow to use Xen hypercalls earlier, during the PEIM stage, but
> XenHypercallLibInit() must be called once the XenInfo HOB is created
> with the HyperPage setup.
>
> Change the return value of XenHypercallLibInit so failure can be
> detected when the call shouldn't fail, but still have the constructor
> always succeed.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - only modify XenHypercallLib, and to the modification of XenPlatformPei
> in a separated patch.
> - Allow XenHypercallLibInit to be called outside the library instead of
> creating a new function, but also return failure on failure,
> and have a new constructor that never fail.
>
> .../Library/XenHypercallLib/XenHypercallLib.inf | 4 ++--
> OvmfPkg/Include/Library/XenHypercallLib.h | 12 ++++++++++++
> .../Library/XenHypercallLib/X86XenHypercall.c | 8 +-------
> OvmfPkg/Library/XenHypercallLib/XenHypercall.c | 16 ++++++++++++++++
> 4 files changed, 31 insertions(+), 9 deletions(-)
>
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> index 1208f0057a..21ce5b4434 100644
> --- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> @@ -12,10 +12,10 @@ [Defines]
> FILE_GUID = B5EE9A32-CA5A-49A8-82E3-ADA4CCB77C7C
> MODULE_TYPE = BASE
> VERSION_STRING = 1.0
> - CONSTRUCTOR = XenHypercallLibInit
> + CONSTRUCTOR = XenHypercallLibConstruct
>
> [Defines.IA32, Defines.X64]
> - LIBRARY_CLASS = XenHypercallLib|DXE_DRIVER UEFI_DRIVER
> + LIBRARY_CLASS = XenHypercallLib|PEIM DXE_DRIVER UEFI_DRIVER
>
> [Defines.ARM, Defines.AARCH64]
> LIBRARY_CLASS = XenHypercallLib
> diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
> index c43822782b..c1491dd652 100644
> --- a/OvmfPkg/Include/Library/XenHypercallLib.h
> +++ b/OvmfPkg/Include/Library/XenHypercallLib.h
> @@ -10,6 +10,18 @@
> #ifndef __XEN_HYPERCALL_LIB_H__
> #define __XEN_HYPERCALL_LIB_H__
>
> +/**
> + To call when the gEfiXenInfoGuid HOB became available after the library init
> + function has already been executed.
> +
> + This allow to make hypercall in the PEIM stage.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +XenHypercallLibInit (
> + VOID
> + );
> +
> /**
> Check if the Xen Hypercall library is able to make calls to the Xen
> hypervisor.
> diff --git a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
> index 27083f924f..f779e46470 100644
> --- a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
> +++ b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
> @@ -59,13 +59,7 @@ XenHypercallLibInit (
>
> GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
> if (GuidHob == NULL) {
> - //
> - // We don't fail library construction, since that has catastrophic
> - // consequences for client modules (whereas those modules may easily be
> - // running on a non-Xen platform). Instead, XenHypercallIsAvailable() above
> - // will return FALSE.
> - //
> - return RETURN_SUCCESS;
> + return RETURN_NOT_FOUND;
> }
> XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> HyperPage = XenInfo->HyperPages;
> diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
> index a2c41a2a69..d4fa802743 100644
> --- a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
> +++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
> @@ -15,6 +15,22 @@
> #include <Library/DebugLib.h>
> #include <Library/XenHypercallLib.h>
>
> +RETURN_STATUS
> +EFIAPI
> +XenHypercallLibConstruct (
> + VOID
> + )
> +{
> + XenHypercallLibInit ();
> + //
> + // We don't fail library construction, since that has catastrophic
> + // consequences for client modules (whereas those modules may easily be
> + // running on a non-Xen platform). Instead, XenHypercallIsAvailable()
> + // will return FALSE.
> + //
> + return RETURN_SUCCESS;
> +}
> +
> UINT64
> EFIAPI
> XenHypercallHvmGetParam (
>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 17/35] OvmfPkg/XenPlatformPei: Reinit XenHypercallLib
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (15 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 16/35] OvmfPkg/XenHypercallLib: Enable it in PEIM Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 15:07 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 18/35] OvmfPkg/XenPlatformPei: Introduce XenHvmloaderDetected Anthony PERARD
` (20 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
The XenPlatformPei needs to make hypercalls, but the XenHypercallLib was
initialised before the HyperPage was ready. Now that XenPlatformPei has
initialised the HyperPage, reinitialise the XenHypercallLib.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- new patch split from XenHypercallLib: Enable it in PEIM.
- check for Lib initialisation failure.
OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 1 +
OvmfPkg/XenPlatformPei/Xen.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
index 4d00206d09..0ef77db92c 100644
--- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
+++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
@@ -59,6 +59,7 @@ [LibraryClasses]
MtrrLib
MemEncryptSevLib
PcdLib
+ XenHypercallLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index c5293498c4..877d776de8 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -26,6 +26,7 @@
#include <Library/ResourcePublicationLib.h>
#include <Library/MtrrLib.h>
#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
+#include <Library/XenHypercallLib.h>
#include "Platform.h"
#include "Xen.h"
@@ -88,6 +89,7 @@ XenConnect (
EFI_XEN_OVMF_INFO *Info;
CHAR8 Sig[sizeof (Info->Signature) + 1];
UINT32 *PVHResetVectorData;
+ RETURN_STATUS Status;
AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
mXenInfo.HyperPages = AllocatePages (TransferPages);
@@ -152,6 +154,13 @@ XenConnect (
sizeof(mXenInfo)
);
+ //
+ // Initialize the XenHypercall library, now that the XenInfo HOB is
+ // available
+ //
+ Status = XenHypercallLibInit ();
+ ASSERT_RETURN_ERROR (Status);
+
return EFI_SUCCESS;
}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 17/35] OvmfPkg/XenPlatformPei: Reinit XenHypercallLib
2019-07-04 14:42 ` [PATCH v3 17/35] OvmfPkg/XenPlatformPei: Reinit XenHypercallLib Anthony PERARD
@ 2019-07-08 15:07 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 15:07 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> The XenPlatformPei needs to make hypercalls, but the XenHypercallLib was
> initialised before the HyperPage was ready. Now that XenPlatformPei has
> initialised the HyperPage, reinitialise the XenHypercallLib.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - new patch split from XenHypercallLib: Enable it in PEIM.
> - check for Lib initialisation failure.
>
> OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 1 +
> OvmfPkg/XenPlatformPei/Xen.c | 9 +++++++++
> 2 files changed, 10 insertions(+)
>
> diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> index 4d00206d09..0ef77db92c 100644
> --- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> +++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> @@ -59,6 +59,7 @@ [LibraryClasses]
> MtrrLib
> MemEncryptSevLib
> PcdLib
> + XenHypercallLib
>
> [Pcd]
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
> diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
> index c5293498c4..877d776de8 100644
> --- a/OvmfPkg/XenPlatformPei/Xen.c
> +++ b/OvmfPkg/XenPlatformPei/Xen.c
> @@ -26,6 +26,7 @@
> #include <Library/ResourcePublicationLib.h>
> #include <Library/MtrrLib.h>
> #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
> +#include <Library/XenHypercallLib.h>
>
> #include "Platform.h"
> #include "Xen.h"
> @@ -88,6 +89,7 @@ XenConnect (
> EFI_XEN_OVMF_INFO *Info;
> CHAR8 Sig[sizeof (Info->Signature) + 1];
> UINT32 *PVHResetVectorData;
> + RETURN_STATUS Status;
>
> AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
> mXenInfo.HyperPages = AllocatePages (TransferPages);
> @@ -152,6 +154,13 @@ XenConnect (
> sizeof(mXenInfo)
> );
>
> + //
> + // Initialize the XenHypercall library, now that the XenInfo HOB is
> + // available
> + //
> + Status = XenHypercallLibInit ();
> + ASSERT_RETURN_ERROR (Status);
> +
> return EFI_SUCCESS;
> }
>
>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 18/35] OvmfPkg/XenPlatformPei: Introduce XenHvmloaderDetected
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (16 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 17/35] OvmfPkg/XenPlatformPei: Reinit XenHypercallLib Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 19/35] OvmfPkg/XenPlatformPei: Reserve hvmloader's memory only when it has run Anthony PERARD
` (19 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
This new XenHvmloaderDetected() return true if the hvmloader firmware
has runned before OVMF.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- Added one sentence in the commit message.
OvmfPkg/XenPlatformPei/Platform.h | 5 +++++
OvmfPkg/XenPlatformPei/Xen.c | 7 +++++++
2 files changed, 12 insertions(+)
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index 77427496c0..925df31f88 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -89,6 +89,11 @@ XenDetect (
VOID
);
+BOOLEAN
+XenHvmloaderDetected (
+ VOID
+ );
+
VOID
AmdSevInitialize (
VOID
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 877d776de8..a90be7bbeb 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -199,6 +199,13 @@ XenDetect (
return FALSE;
}
+BOOLEAN
+XenHvmloaderDetected (
+ VOID
+ )
+{
+ return (mXenHvmloaderInfo != NULL);
+}
VOID
XenPublishRamRegions (
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 19/35] OvmfPkg/XenPlatformPei: Reserve hvmloader's memory only when it has run
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (17 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 18/35] OvmfPkg/XenPlatformPei: Introduce XenHvmloaderDetected Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 20/35] OvmfPkg/XenPlatformPei: Setup HyperPages earlier Anthony PERARD
` (18 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Reserve hvmloader's memory only when it has run.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix empty commit message body
OvmfPkg/XenPlatformPei/Xen.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index a90be7bbeb..37e9cff4b4 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -272,7 +272,9 @@ InitializeXen (
// Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
// This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
//
- AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
+ if (XenHvmloaderDetected ()) {
+ AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
+ }
PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
ASSERT_RETURN_ERROR (PcdStatus);
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 20/35] OvmfPkg/XenPlatformPei: Setup HyperPages earlier
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (18 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 19/35] OvmfPkg/XenPlatformPei: Reserve hvmloader's memory only when it has run Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 21/35] OvmfPkg/XenPlatformPei: Introduce XenPvhDetected Anthony PERARD
` (17 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
We are going to need to make an hypercall in order to retreive the E820
table from the hypervisor before been able to setup the memory.
Calling XenConnect earlier will allow to setup the XenHypercallLib
earlier to allow to make hypercalls.
While here, add some comments in XenConnect().
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
OvmfPkg/XenPlatformPei/Platform.h | 5 +++++
OvmfPkg/XenPlatformPei/Platform.c | 2 ++
OvmfPkg/XenPlatformPei/Xen.c | 23 ++++++++++++-----------
3 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index 925df31f88..4a80057bdc 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -79,6 +79,11 @@ InstallClearCacheCallback (
VOID
);
+EFI_STATUS
+XenConnect (
+ VOID
+ );
+
EFI_STATUS
InitializeXen (
VOID
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
index c97a2fb6c1..52f6048ca4 100644
--- a/OvmfPkg/XenPlatformPei/Platform.c
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -416,6 +416,8 @@ InitializeXenPlatform (
CpuDeadLoop ();
}
+ XenConnect ();
+
BootModeInitialization ();
AddressWidthInitialization ();
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 37e9cff4b4..7d1696bb22 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -72,14 +72,11 @@ XenGetE820Map (
/**
Connects to the Hypervisor.
- @param XenLeaf CPUID index used to connect.
-
@return EFI_STATUS
**/
EFI_STATUS
XenConnect (
- UINT32 XenLeaf
)
{
UINT32 Index;
@@ -91,7 +88,13 @@ XenConnect (
UINT32 *PVHResetVectorData;
RETURN_STATUS Status;
- AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
+ ASSERT (mXenLeaf != 0);
+
+ //
+ // Prepare HyperPages to be able to make hypercalls
+ //
+
+ AsmCpuid (mXenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
mXenInfo.HyperPages = AllocatePages (TransferPages);
if (!mXenInfo.HyperPages) {
return EFI_OUT_OF_RESOURCES;
@@ -103,7 +106,11 @@ XenConnect (
(Index << EFI_PAGE_SHIFT) + Index);
}
- AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);
+ //
+ // Find out the Xen version
+ //
+
+ AsmCpuid (mXenLeaf + 1, &XenVersion, NULL, NULL, NULL);
DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",
XenVersion >> 16, XenVersion & 0xFFFF));
mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
@@ -262,12 +269,6 @@ InitializeXen (
{
RETURN_STATUS PcdStatus;
- if (mXenLeaf == 0) {
- return EFI_NOT_FOUND;
- }
-
- XenConnect (mXenLeaf);
-
//
// Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
// This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 21/35] OvmfPkg/XenPlatformPei: Introduce XenPvhDetected
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (19 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 20/35] OvmfPkg/XenPlatformPei: Setup HyperPages earlier Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 22/35] OvmfPkg: Import XENMEM_memory_map hypercall to Xen/memory.h Anthony PERARD
` (16 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
XenPvhDetected() can be used to figure out if OVMF has started via the
Xen PVH entry point.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
OvmfPkg/XenPlatformPei/Platform.h | 5 +++++
OvmfPkg/XenPlatformPei/Xen.c | 13 +++++++++++++
2 files changed, 18 insertions(+)
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index 4a80057bdc..db9a62572f 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -99,6 +99,11 @@ XenHvmloaderDetected (
VOID
);
+BOOLEAN
+XenPvhDetected (
+ VOID
+ );
+
VOID
AmdSevInitialize (
VOID
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 7d1696bb22..188e831c5c 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -214,6 +214,19 @@ XenHvmloaderDetected (
return (mXenHvmloaderInfo != NULL);
}
+BOOLEAN
+XenPvhDetected (
+ VOID
+ )
+{
+ //
+ // This function should only be used after XenConnect
+ //
+ ASSERT (mXenInfo.VersionMajor != 0);
+
+ return mXenHvmloaderInfo == NULL;
+}
+
VOID
XenPublishRamRegions (
VOID
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 22/35] OvmfPkg: Import XENMEM_memory_map hypercall to Xen/memory.h
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (20 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 21/35] OvmfPkg/XenPlatformPei: Introduce XenPvhDetected Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 23/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall Anthony PERARD
` (15 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
The informations to make a XENMEM_memory_map hypercall is copied over
from the public header of the Xen Project, with the type name modified
to build on OVMF.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- expanded the "This" that was starting the commit message body.
OvmfPkg/Include/IndustryStandard/Xen/memory.h | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/OvmfPkg/Include/IndustryStandard/Xen/memory.h b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
index 81e981331a..4a33a26d4e 100644
--- a/OvmfPkg/Include/IndustryStandard/Xen/memory.h
+++ b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
@@ -65,6 +65,29 @@ struct xen_remove_from_physmap {
typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
+/*
+ * Returns the pseudo-physical memory map as it was when the domain
+ * was started (specified by XENMEM_set_memory_map).
+ * arg == addr of xen_memory_map_t.
+ */
+#define XENMEM_memory_map 9
+struct xen_memory_map {
+ /*
+ * On call the number of entries which can be stored in buffer. On
+ * return the number of entries which have been stored in
+ * buffer.
+ */
+ UINT32 nr_entries;
+
+ /*
+ * Entries in the buffer are in the same format as returned by the
+ * BIOS INT 0x15 EAX=0xE820 call.
+ */
+ XEN_GUEST_HANDLE(void) buffer;
+};
+typedef struct xen_memory_map xen_memory_map_t;
+DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
+
#endif /* __XEN_PUBLIC_MEMORY_H__ */
/*
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 23/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (21 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 22/35] OvmfPkg: Import XENMEM_memory_map hypercall to Xen/memory.h Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection Anthony PERARD
` (14 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
When the Xen PVH entry point has been used, hvmloader hasn't run and
hasn't prepared an E820 table. The only way left to get an E820 table
is to ask Xen via an hypercall, the call can only be made once so keep
the result cached for later.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix commit message
- add 'm' prefix to the global variables
and make them static
OvmfPkg/XenPlatformPei/Xen.c | 46 +++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 188e831c5c..cbfd8058fc 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -27,6 +27,7 @@
#include <Library/MtrrLib.h>
#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
#include <Library/XenHypercallLib.h>
+#include <IndustryStandard/Xen/memory.h>
#include "Platform.h"
#include "Xen.h"
@@ -40,6 +41,8 @@ EFI_XEN_INFO mXenInfo;
// Only the E820 table is used by OVMF.
//
EFI_XEN_OVMF_INFO *mXenHvmloaderInfo;
+STATIC EFI_E820_ENTRY64 mE820Entries[128];
+STATIC UINT32 mE820EntriesCount;
/**
Returns E820 map provided by Xen
@@ -55,6 +58,12 @@ XenGetE820Map (
UINT32 *Count
)
{
+ INTN ReturnCode;
+ xen_memory_map_t Parameters;
+ UINTN LoopIndex;
+ UINTN Index;
+ EFI_E820_ENTRY64 TmpEntry;
+
//
// Get E820 produced by hvmloader
//
@@ -66,7 +75,42 @@ XenGetE820Map (
return EFI_SUCCESS;
}
- return EFI_NOT_FOUND;
+ //
+ // Otherwise, get the E820 table from the Xen hypervisor
+ //
+
+ if (mE820EntriesCount > 0) {
+ *Entries = mE820Entries;
+ *Count = mE820EntriesCount;
+ return EFI_SUCCESS;
+ }
+
+ Parameters.nr_entries = 128;
+ set_xen_guest_handle (Parameters.buffer, mE820Entries);
+
+ // Returns a errno
+ ReturnCode = XenHypercallMemoryOp (XENMEM_memory_map, &Parameters);
+ ASSERT (ReturnCode == 0);
+
+ mE820EntriesCount = Parameters.nr_entries;
+
+ //
+ // Sort E820 entries
+ //
+ for (LoopIndex = 1; LoopIndex < mE820EntriesCount; LoopIndex++) {
+ for (Index = LoopIndex; Index < mE820EntriesCount; Index++) {
+ if (mE820Entries[Index - 1].BaseAddr > mE820Entries[Index].BaseAddr) {
+ TmpEntry = mE820Entries[Index];
+ mE820Entries[Index] = mE820Entries[Index - 1];
+ mE820Entries[Index - 1] = TmpEntry;
+ }
+ }
+ }
+
+ *Count = mE820EntriesCount;
+ *Entries = mE820Entries;
+
+ return EFI_SUCCESS;
}
/**
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (22 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 23/35] OvmfPkg/XenPlatformPei: no hvmloader: get the E820 table via hypercall Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-15 14:15 ` roger.pau
2019-07-04 14:42 ` [PATCH v3 25/35] OvmfPkg/XenPlatformPei: Reserve VGA memory region, to boot Linux Anthony PERARD
` (13 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD, Andrew Cooper, Roger Pau Monné
When running as a Xen PVH guest, there is no CMOS to read the memory
size from. Rework GetSystemMemorySize(Below|Above)4gb() so they can
works without CMOS by reading the e820 table.
Rework XenPublishRamRegions for PVH, handle the Reserve type and explain
about the ACPI type. MTRR settings aren't modified anymore, on HVM, it's
already done by hvmloader, on PVH it is supposed to have sane default.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
Comment for Xen people:
About MTRR, should we redo the setting in OVMF? Even if in both case of
PVH and HVM, something would have setup the default type to write back
and handle a few other ranges like PCI hole, hvmloader for HVM or and
libxc I think for PVH.
(For PVH, it's in the spec as well
https://xenbits.xenproject.org/docs/unstable/misc/pvh.html#mtrr )
OvmfPkg/XenPlatformPei/Platform.h | 6 +++
OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++
OvmfPkg/XenPlatformPei/Xen.c | 47 ++++++++++++++------
3 files changed, 111 insertions(+), 13 deletions(-)
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index db9a62572f..e8e0b835a5 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -114,6 +114,12 @@ XenPublishRamRegions (
VOID
);
+EFI_STATUS
+XenGetE820Map (
+ EFI_E820_ENTRY64 **Entries,
+ UINT32 *Count
+ );
+
extern EFI_BOOT_MODE mBootMode;
extern UINT8 mPhysMemAddressWidth;
diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
index cb7dd93ad6..3e33e7f414 100644
--- a/OvmfPkg/XenPlatformPei/MemDetect.c
+++ b/OvmfPkg/XenPlatformPei/MemDetect.c
@@ -96,6 +96,47 @@ Q35TsegMbytesInitialization (
mQ35TsegMbytes = ExtendedTsegMbytes;
}
+STATIC
+UINT64
+GetHighestSystemMemoryAddress (
+ BOOLEAN Below4gb
+ )
+{
+ EFI_E820_ENTRY64 *E820Map;
+ UINT32 E820EntriesCount;
+ EFI_E820_ENTRY64 *Entry;
+ EFI_STATUS Status;
+ UINT32 Loop;
+ UINT64 HighestAddress;
+ UINT64 EntryEnd;
+
+ HighestAddress = 0;
+
+ Status = XenGetE820Map (&E820Map, &E820EntriesCount);
+ ASSERT_EFI_ERROR (Status);
+
+ for (Loop = 0; Loop < E820EntriesCount; Loop++) {
+ Entry = E820Map + Loop;
+ EntryEnd = Entry->BaseAddr + Entry->Length;
+
+ if (Entry->Type == EfiAcpiAddressRangeMemory &&
+ EntryEnd > HighestAddress) {
+
+ if (Below4gb && (EntryEnd <= BASE_4GB)) {
+ HighestAddress = EntryEnd;
+ } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
+ HighestAddress = EntryEnd;
+ }
+ }
+ }
+
+ //
+ // Round down the end address.
+ //
+ HighestAddress &= ~(UINT64)EFI_PAGE_MASK;
+
+ return HighestAddress;
+}
UINT32
GetSystemMemorySizeBelow4gb (
@@ -105,6 +146,19 @@ GetSystemMemorySizeBelow4gb (
UINT8 Cmos0x34;
UINT8 Cmos0x35;
+ //
+ // In PVH case, there is no CMOS, we have to calculate the memory size
+ // from parsing the E820
+ //
+ if (XenPvhDetected ()) {
+ UINT64 HighestAddress;
+
+ HighestAddress = GetHighestSystemMemoryAddress (TRUE);
+ ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);
+
+ return HighestAddress;
+ }
+
//
// CMOS 0x34/0x35 specifies the system memory above 16 MB.
// * CMOS(0x35) is the high byte
@@ -129,6 +183,23 @@ GetSystemMemorySizeAbove4gb (
UINT32 Size;
UINTN CmosIndex;
+ //
+ // In PVH case, there is no CMOS, we have to calculate the memory size
+ // from parsing the E820
+ //
+ if (XenPvhDetected ()) {
+ UINT64 HighestAddress;
+
+ HighestAddress = GetHighestSystemMemoryAddress (FALSE);
+ ASSERT (HighestAddress == 0 || HighestAddress >= BASE_4GB);
+
+ if (HighestAddress >= BASE_4GB) {
+ HighestAddress -= BASE_4GB;
+ }
+
+ return HighestAddress;
+ }
+
//
// CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
// * CMOS(0x5d) is the most significant size byte
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index cbfd8058fc..62a2c3ed93 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -279,6 +279,8 @@ XenPublishRamRegions (
EFI_E820_ENTRY64 *E820Map;
UINT32 E820EntriesCount;
EFI_STATUS Status;
+ EFI_E820_ENTRY64 *Entry;
+ UINTN Index;
DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
@@ -287,26 +289,45 @@ XenPublishRamRegions (
//
E820EntriesCount = 0;
Status = XenGetE820Map (&E820Map, &E820EntriesCount);
-
ASSERT_EFI_ERROR (Status);
- if (E820EntriesCount > 0) {
- EFI_E820_ENTRY64 *Entry;
- UINT32 Loop;
+ for (Index = 0; Index < E820EntriesCount; Index++) {
+ UINT64 Base;
+ UINT64 End;
- for (Loop = 0; Loop < E820EntriesCount; Loop++) {
- Entry = E820Map + Loop;
+ Entry = &E820Map[Index];
+
+ //
+ // Round up the start address, and round down the end address.
+ //
+ Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
+ End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
+
+ switch (Entry->Type) {
+ case EfiAcpiAddressRangeMemory:
+ AddMemoryRangeHob (Base, End);
+ break;
+ case EfiAcpiAddressRangeACPI:
+ //
+ // Ignore, OVMF should read the ACPI tables and provide them to linux
+ // from a different location.
+ //
+ break;
+ case EfiAcpiAddressRangeReserved:
//
- // Only care about RAM
+ // Avoid ranges marked as reserved in the e820 table provided by
+ // hvmloader as it conflicts with an other aperture.
+ // error message: CpuDxe: IntersectMemoryDescriptor:
+ // desc [FC000000, 100000000) type 1 cap 8700000000026001
+ // conflicts with aperture [FEE00000, FEE01000) cap 1
//
- if (Entry->Type != EfiAcpiAddressRangeMemory) {
- continue;
+ if (!XenHvmloaderDetected ()) {
+ AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
}
-
- AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
-
- MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
+ break;
+ default:
+ break;
}
}
}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-04 14:42 ` [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection Anthony PERARD
@ 2019-07-15 14:15 ` roger.pau
2019-07-22 14:53 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: roger.pau @ 2019-07-15 14:15 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> When running as a Xen PVH guest, there is no CMOS to read the memory
> size from. Rework GetSystemMemorySize(Below|Above)4gb() so they can
> works without CMOS by reading the e820 table.
>
> Rework XenPublishRamRegions for PVH, handle the Reserve type and explain
> about the ACPI type. MTRR settings aren't modified anymore, on HVM, it's
> already done by hvmloader, on PVH it is supposed to have sane default.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> ---
>
> Notes:
> Comment for Xen people:
> About MTRR, should we redo the setting in OVMF? Even if in both case of
> PVH and HVM, something would have setup the default type to write back
> and handle a few other ranges like PCI hole, hvmloader for HVM or and
> libxc I think for PVH.
That's a tricky question. Ideally we would like the firmware (OVMF) to
take care of that, because it already has code to do so. Problem here
is that PVH can also be booted without firmware, in which case it
needs the hypervisor to have setup some sane initial MTRR state.
The statement in the PVH document about initial MTRR state is vague
enough that allows Xen to boot into the guest with a minimal MTRR
state, that can for example not contain UC regions for the MMIO
regions of passed through devices, hence I think OVMF should be in
charge of creating a more complete MTRR state if possible.
Is this something OVMF already has logic for?
Also accounting for the MMIO regions of devices?
> (For PVH, it's in the spec as well
> https://xenbits.xenproject.org/docs/unstable/misc/pvh.html#mtrr )
>
> OvmfPkg/XenPlatformPei/Platform.h | 6 +++
> OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++
> OvmfPkg/XenPlatformPei/Xen.c | 47 ++++++++++++++------
> 3 files changed, 111 insertions(+), 13 deletions(-)
>
> diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
> index db9a62572f..e8e0b835a5 100644
> --- a/OvmfPkg/XenPlatformPei/Platform.h
> +++ b/OvmfPkg/XenPlatformPei/Platform.h
> @@ -114,6 +114,12 @@ XenPublishRamRegions (
> VOID
> );
>
> +EFI_STATUS
> +XenGetE820Map (
> + EFI_E820_ENTRY64 **Entries,
> + UINT32 *Count
> + );
> +
> extern EFI_BOOT_MODE mBootMode;
>
> extern UINT8 mPhysMemAddressWidth;
> diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> index cb7dd93ad6..3e33e7f414 100644
> --- a/OvmfPkg/XenPlatformPei/MemDetect.c
> +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> @@ -96,6 +96,47 @@ Q35TsegMbytesInitialization (
> mQ35TsegMbytes = ExtendedTsegMbytes;
> }
>
> +STATIC
> +UINT64
> +GetHighestSystemMemoryAddress (
> + BOOLEAN Below4gb
> + )
> +{
> + EFI_E820_ENTRY64 *E820Map;
> + UINT32 E820EntriesCount;
> + EFI_E820_ENTRY64 *Entry;
> + EFI_STATUS Status;
> + UINT32 Loop;
> + UINT64 HighestAddress;
> + UINT64 EntryEnd;
> +
> + HighestAddress = 0;
> +
> + Status = XenGetE820Map (&E820Map, &E820EntriesCount);
You could maybe initialize this as a global to avoid having to issue
a hypercall each time you need to get something from the memory map.
> + ASSERT_EFI_ERROR (Status);
> +
> + for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> + Entry = E820Map + Loop;
> + EntryEnd = Entry->BaseAddr + Entry->Length;
> +
> + if (Entry->Type == EfiAcpiAddressRangeMemory &&
> + EntryEnd > HighestAddress) {
> +
> + if (Below4gb && (EntryEnd <= BASE_4GB)) {
> + HighestAddress = EntryEnd;
> + } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
> + HighestAddress = EntryEnd;
> + }
> + }
> + }
> +
> + //
> + // Round down the end address.
> + //
> + HighestAddress &= ~(UINT64)EFI_PAGE_MASK;
> +
> + return HighestAddress;
You could do the rounding on the return statement.
> +}
>
> UINT32
> GetSystemMemorySizeBelow4gb (
> @@ -105,6 +146,19 @@ GetSystemMemorySizeBelow4gb (
> UINT8 Cmos0x34;
> UINT8 Cmos0x35;
>
> + //
> + // In PVH case, there is no CMOS, we have to calculate the memory size
> + // from parsing the E820
> + //
> + if (XenPvhDetected ()) {
IIRC on HVM you can also get the memory map from the hypercall, in
which case you could use the same code path for both HVM and PVH.
> + UINT64 HighestAddress;
> +
> + HighestAddress = GetHighestSystemMemoryAddress (TRUE);
> + ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);
> +
> + return HighestAddress;
The name of the function here is GetSystemMemorySizeBelow4gb, but you
are returning the highest memory address in the range, is this
expected?
ie: highest address != memory size
On HVM there are quite some holes in the memory map, and nothing
guarantees there are no memory regions after the holes or non-RAM
regions.
> + }
> +
> //
> // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> // * CMOS(0x35) is the high byte
> @@ -129,6 +183,23 @@ GetSystemMemorySizeAbove4gb (
> UINT32 Size;
> UINTN CmosIndex;
>
> + //
> + // In PVH case, there is no CMOS, we have to calculate the memory size
> + // from parsing the E820
> + //
> + if (XenPvhDetected ()) {
> + UINT64 HighestAddress;
> +
> + HighestAddress = GetHighestSystemMemoryAddress (FALSE);
> + ASSERT (HighestAddress == 0 || HighestAddress >= BASE_4GB);
> +
> + if (HighestAddress >= BASE_4GB) {
> + HighestAddress -= BASE_4GB;
> + }
> +
> + return HighestAddress;
> + }
> +
> //
> // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> // * CMOS(0x5d) is the most significant size byte
> diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
> index cbfd8058fc..62a2c3ed93 100644
> --- a/OvmfPkg/XenPlatformPei/Xen.c
> +++ b/OvmfPkg/XenPlatformPei/Xen.c
> @@ -279,6 +279,8 @@ XenPublishRamRegions (
> EFI_E820_ENTRY64 *E820Map;
> UINT32 E820EntriesCount;
> EFI_STATUS Status;
> + EFI_E820_ENTRY64 *Entry;
> + UINTN Index;
>
> DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
>
> @@ -287,26 +289,45 @@ XenPublishRamRegions (
> //
> E820EntriesCount = 0;
> Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> -
> ASSERT_EFI_ERROR (Status);
>
> - if (E820EntriesCount > 0) {
> - EFI_E820_ENTRY64 *Entry;
> - UINT32 Loop;
> + for (Index = 0; Index < E820EntriesCount; Index++) {
> + UINT64 Base;
> + UINT64 End;
>
> - for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> - Entry = E820Map + Loop;
> + Entry = &E820Map[Index];
>
> +
> + //
> + // Round up the start address, and round down the end address.
> + //
> + Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
> + End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
> +
> + switch (Entry->Type) {
> + case EfiAcpiAddressRangeMemory:
> + AddMemoryRangeHob (Base, End);
> + break;
> + case EfiAcpiAddressRangeACPI:
> + //
> + // Ignore, OVMF should read the ACPI tables and provide them to linux
> + // from a different location.
Will OVMF also parse dynamic tables to check for references there?
> + //
> + break;
> + case EfiAcpiAddressRangeReserved:
> //
> - // Only care about RAM
> + // Avoid ranges marked as reserved in the e820 table provided by
> + // hvmloader as it conflicts with an other aperture.
I think you want the last part of the sentence to be: '... as it
conflicts with other apertures.'
I think however that you should make sure ranges marked as reserved in
the original memory map also end up in the final one, hence
overlapping ranges should be merged, instead of discarded.
> + // error message: CpuDxe: IntersectMemoryDescriptor:
> + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> + // conflicts with aperture [FEE00000, FEE01000) cap 1
> //
> - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> - continue;
> + if (!XenHvmloaderDetected ()) {
> + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
This special casing for PVH looks weird, ideally we would like to use
the same code path, or else it should be explicitly mentioned why PVH
has diverging behaviour.
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-15 14:15 ` roger.pau
@ 2019-07-22 14:53 ` Anthony PERARD
2019-07-22 19:45 ` Laszlo Ersek
2019-07-23 9:42 ` Roger Pau Monné
0 siblings, 2 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-22 14:53 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > When running as a Xen PVH guest, there is no CMOS to read the memory
> > size from. Rework GetSystemMemorySize(Below|Above)4gb() so they can
> > works without CMOS by reading the e820 table.
> >
> > Rework XenPublishRamRegions for PVH, handle the Reserve type and explain
> > about the ACPI type. MTRR settings aren't modified anymore, on HVM, it's
> > already done by hvmloader, on PVH it is supposed to have sane default.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> > Acked-by: Laszlo Ersek <lersek@redhat.com>
> > ---
> >
> > Notes:
> > Comment for Xen people:
> > About MTRR, should we redo the setting in OVMF? Even if in both case of
> > PVH and HVM, something would have setup the default type to write back
> > and handle a few other ranges like PCI hole, hvmloader for HVM or and
> > libxc I think for PVH.
>
> That's a tricky question. Ideally we would like the firmware (OVMF) to
> take care of that, because it already has code to do so. Problem here
> is that PVH can also be booted without firmware, in which case it
> needs the hypervisor to have setup some sane initial MTRR state.
>
> The statement in the PVH document about initial MTRR state is vague
> enough that allows Xen to boot into the guest with a minimal MTRR
> state, that can for example not contain UC regions for the MMIO
> regions of passed through devices, hence I think OVMF should be in
> charge of creating a more complete MTRR state if possible.
>
> Is this something OVMF already has logic for?
Well, there are some logic but it's for QEMU (and uses an interface that
isn't available when running on Xen, fwcfg).
The logic that was there for Xen HVM was very simple, a single set
cache-write-back for the RAM, that's why I remove it (and because I'm
not sure yet I figured out how to run the mtrr functions correctly in
OVMF).
I probably going to have to write a new logic which would rewrite the
MTRR from scratch instead of relying on the existing setup.
> Also accounting for the MMIO regions of devices?
I'll have to dig deeper into OVMF codes, and PCI device handling. On
HVM, we have a different logic than the one for QEMU, OVMF only scan
what hvmloader have done instead of re-setup the pci devices. I'm
probably missing other stuff.
> > diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> > index cb7dd93ad6..3e33e7f414 100644
> > --- a/OvmfPkg/XenPlatformPei/MemDetect.c
> > +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> > @@ -96,6 +96,47 @@ Q35TsegMbytesInitialization (
> > mQ35TsegMbytes = ExtendedTsegMbytes;
> > }
> >
> > +STATIC
> > +UINT64
> > +GetHighestSystemMemoryAddress (
> > + BOOLEAN Below4gb
> > + )
> > +{
> > + EFI_E820_ENTRY64 *E820Map;
> > + UINT32 E820EntriesCount;
> > + EFI_E820_ENTRY64 *Entry;
> > + EFI_STATUS Status;
> > + UINT32 Loop;
> > + UINT64 HighestAddress;
> > + UINT64 EntryEnd;
> > +
> > + HighestAddress = 0;
> > +
> > + Status = XenGetE820Map (&E820Map, &E820EntriesCount);
>
> You could maybe initialize this as a global to avoid having to issue
> a hypercall each time you need to get something from the memory map.
That function does that, it only make the hypercall once. (The hypercall
can only be made once anyway, the second time Xen doesn't return the
map.)
> > + ASSERT_EFI_ERROR (Status);
> > +
> > + for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> > + Entry = E820Map + Loop;
> > + EntryEnd = Entry->BaseAddr + Entry->Length;
> > +
> > + if (Entry->Type == EfiAcpiAddressRangeMemory &&
> > + EntryEnd > HighestAddress) {
> > +
> > + if (Below4gb && (EntryEnd <= BASE_4GB)) {
> > + HighestAddress = EntryEnd;
> > + } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
> > + HighestAddress = EntryEnd;
> > + }
> > + }
> > + }
> > +
> > + //
> > + // Round down the end address.
> > + //
> > + HighestAddress &= ~(UINT64)EFI_PAGE_MASK;
> > +
> > + return HighestAddress;
>
> You could do the rounding on the return statement.
Yes, I think that can be done.
> > +}
> >
> > UINT32
> > GetSystemMemorySizeBelow4gb (
> > @@ -105,6 +146,19 @@ GetSystemMemorySizeBelow4gb (
> > UINT8 Cmos0x34;
> > UINT8 Cmos0x35;
> >
> > + //
> > + // In PVH case, there is no CMOS, we have to calculate the memory size
> > + // from parsing the E820
> > + //
> > + if (XenPvhDetected ()) {
>
> IIRC on HVM you can also get the memory map from the hypercall, in
> which case you could use the same code path for both HVM and PVH.
I think that wouldn't work because in my experiment, the hypercall would
only return the map the first time (at least on PVH). hvmloader already
make the hypercall so OVMF can't.
On the other hand, XenGetE820Map() return an E820 map, it doesn't matter
if it's the one passed by hvmloader, or the one we've got directly from
Xen. So I guess we could ignore what hvmloader have written in the CMOS
and use the information in the e820 directly. But I think I let this
change for future patch.
> > + UINT64 HighestAddress;
> > +
> > + HighestAddress = GetHighestSystemMemoryAddress (TRUE);
> > + ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);
> > +
> > + return HighestAddress;
>
> The name of the function here is GetSystemMemorySizeBelow4gb, but you
> are returning the highest memory address in the range, is this
> expected?
>
> ie: highest address != memory size
>
> On HVM there are quite some holes in the memory map, and nothing
> guarantees there are no memory regions after the holes or non-RAM
> regions.
I think that's what is expected by caller of the function.
> > + }
> > +
> > //
> > // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> > // * CMOS(0x35) is the high byte
> > diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
> > index cbfd8058fc..62a2c3ed93 100644
> > --- a/OvmfPkg/XenPlatformPei/Xen.c
> > +++ b/OvmfPkg/XenPlatformPei/Xen.c
> > @@ -279,6 +279,8 @@ XenPublishRamRegions (
> > EFI_E820_ENTRY64 *E820Map;
> > UINT32 E820EntriesCount;
> > EFI_STATUS Status;
> > + EFI_E820_ENTRY64 *Entry;
> > + UINTN Index;
> >
> > DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
> >
> > @@ -287,26 +289,45 @@ XenPublishRamRegions (
> > //
> > E820EntriesCount = 0;
> > Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> > -
> > ASSERT_EFI_ERROR (Status);
> >
> > - if (E820EntriesCount > 0) {
> > - EFI_E820_ENTRY64 *Entry;
> > - UINT32 Loop;
> > + for (Index = 0; Index < E820EntriesCount; Index++) {
> > + UINT64 Base;
> > + UINT64 End;
> >
> > - for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> > - Entry = E820Map + Loop;
> > + Entry = &E820Map[Index];
> >
> > +
> > + //
> > + // Round up the start address, and round down the end address.
> > + //
> > + Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
> > + End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
> > +
> > + switch (Entry->Type) {
> > + case EfiAcpiAddressRangeMemory:
> > + AddMemoryRangeHob (Base, End);
> > + break;
> > + case EfiAcpiAddressRangeACPI:
> > + //
> > + // Ignore, OVMF should read the ACPI tables and provide them to linux
> > + // from a different location.
>
> Will OVMF also parse dynamic tables to check for references there?
I haven't looked at what OVMF does with the ACPI tables, but Linux seems
fine. I've compared the boot output of linux running as PVH vs booted
via OVMF. Beside the location of the table been different, the number of
table where the same, I don't remember other difference.
> > + //
> > + break;
> > + case EfiAcpiAddressRangeReserved:
> > //
> > - // Only care about RAM
> > + // Avoid ranges marked as reserved in the e820 table provided by
> > + // hvmloader as it conflicts with an other aperture.
>
> I think you want the last part of the sentence to be: '... as it
> conflicts with other apertures.'
>
> I think however that you should make sure ranges marked as reserved in
> the original memory map also end up in the final one, hence
> overlapping ranges should be merged, instead of discarded.
I'll look into that.
> > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > //
> > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > - continue;
> > + if (!XenHvmloaderDetected ()) {
> > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
>
> This special casing for PVH looks weird, ideally we would like to use
> the same code path, or else it should be explicitly mentioned why PVH
> has diverging behaviour.
I think hvmloader is the issue rather than PVH. Here is part of the
"memory map" as found in hvmloader/config.h:
/* Special BIOS mappings, etc. are allocated from here upwards... */
#define RESERVED_MEMBASE 0xFC000000
/* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
#define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
#define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
#define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
and hvmloader simply creates a single e820 reserved entry, from
RESERVED_MEMBASE to the top of 4GB. It's probably too much.
If hvmloader only reserved
ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
to special case hvmloader. As far as I know 0xfee00000 isn't a special
bios mapping, but something the hardware provides.
Anyway, thanks for the feedback, there's probably quite a bit to do to
cleanup the memory stuff. I do think about one day running OVMF without
running hvmloader first :-), but there's a bit more to do.
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-22 14:53 ` Anthony PERARD
@ 2019-07-22 19:45 ` Laszlo Ersek
2019-07-22 23:08 ` Laszlo Ersek
2019-07-23 9:42 ` Roger Pau Monné
1 sibling, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-22 19:45 UTC (permalink / raw)
To: Anthony PERARD, Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper
On 07/22/19 16:53, Anthony PERARD wrote:
> On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
>> On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
>>> When running as a Xen PVH guest, there is no CMOS to read the memory
>>> size from. Rework GetSystemMemorySize(Below|Above)4gb() so they can
>>> works without CMOS by reading the e820 table.
>>>
>>> Rework XenPublishRamRegions for PVH, handle the Reserve type and explain
>>> about the ACPI type. MTRR settings aren't modified anymore, on HVM, it's
>>> already done by hvmloader, on PVH it is supposed to have sane default.
>>>
>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
>>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>>> Acked-by: Laszlo Ersek <lersek@redhat.com>
>>> ---
>>>
>>> Notes:
>>> Comment for Xen people:
>>> About MTRR, should we redo the setting in OVMF? Even if in both case of
>>> PVH and HVM, something would have setup the default type to write back
>>> and handle a few other ranges like PCI hole, hvmloader for HVM or and
>>> libxc I think for PVH.
>>
>> That's a tricky question. Ideally we would like the firmware (OVMF) to
>> take care of that, because it already has code to do so. Problem here
>> is that PVH can also be booted without firmware, in which case it
>> needs the hypervisor to have setup some sane initial MTRR state.
>>
>> The statement in the PVH document about initial MTRR state is vague
>> enough that allows Xen to boot into the guest with a minimal MTRR
>> state, that can for example not contain UC regions for the MMIO
>> regions of passed through devices, hence I think OVMF should be in
>> charge of creating a more complete MTRR state if possible.
>>
>> Is this something OVMF already has logic for?
>
> Well, there are some logic but it's for QEMU (and uses an interface that
> isn't available when running on Xen, fwcfg).
>
> The logic that was there for Xen HVM was very simple, a single set
> cache-write-back for the RAM, that's why I remove it (and because I'm
> not sure yet I figured out how to run the mtrr functions correctly in
> OVMF).
>
> I probably going to have to write a new logic which would rewrite the
> MTRR from scratch instead of relying on the existing setup.
MTRR setup is complex in OVMF, in comparison to firmware that runs on
physical machines, because:
- the physical RAM size can change from boot to boot, with almost total
freedom, and that can incur some unexpected changes in the physical RAM
map too (i.e. affect not just the end, but holes)
- the number of variable MTRRs is severely limited and can't cover an
arbitrary physical RAM map. And, some platform-independent modules in
edk2 consume variable MTRRs too, via gDS->SetMemorySpaceAttributes(), so
we have to be very conservative with even those variable MTRRs that exist.
Even on QEMU i440fx & pc, we've *just* made OVMF cope with an arbitrary
guest RAM size (that is, beyond 128MB), and that logic relies on some
open-coded board-specific knowledge about low (<4G) RAM size. So much so
that, on i440fx, we place the 32-bit PCI IOMMU aperture based on what we
can configure with a minimal amount of variable MTRRs, and not vice
versa (i.e. we don't first set the 32-bit MMIO aperture and then attempt
to mark it as uncached). Please see:
https://bugzilla.tianocore.org/show_bug.cgi?id=1814
This is one of the nastiest parts of OVMF. (PlatformPei is, in general.)
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-22 19:45 ` Laszlo Ersek
@ 2019-07-22 23:08 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-22 23:08 UTC (permalink / raw)
To: Anthony PERARD, Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper
On 07/22/19 21:45, Laszlo Ersek wrote:
> we place the 32-bit PCI IOMMU aperture based on [...]
Do I get a medal for this hugely confusing typo? :)
In earnest, I'm sorry about it -- my comment had nothing to do with
"IOMMU"; I meant "MMIO". (At least I got it right in the rest of the email.)
Sorry!
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-22 14:53 ` Anthony PERARD
2019-07-22 19:45 ` Laszlo Ersek
@ 2019-07-23 9:42 ` Roger Pau Monné
2019-07-23 16:06 ` Anthony PERARD
2019-07-24 16:17 ` Anthony PERARD
1 sibling, 2 replies; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-23 9:42 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > When running as a Xen PVH guest, there is no CMOS to read the memory
> > > size from. Rework GetSystemMemorySize(Below|Above)4gb() so they can
> > > works without CMOS by reading the e820 table.
> > >
> > > Rework XenPublishRamRegions for PVH, handle the Reserve type and explain
> > > about the ACPI type. MTRR settings aren't modified anymore, on HVM, it's
> > > already done by hvmloader, on PVH it is supposed to have sane default.
> > >
> > > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> > > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> > > Acked-by: Laszlo Ersek <lersek@redhat.com>
> > > ---
> > >
> > > Notes:
> > > Comment for Xen people:
> > > About MTRR, should we redo the setting in OVMF? Even if in both case of
> > > PVH and HVM, something would have setup the default type to write back
> > > and handle a few other ranges like PCI hole, hvmloader for HVM or and
> > > libxc I think for PVH.
> >
> > That's a tricky question. Ideally we would like the firmware (OVMF) to
> > take care of that, because it already has code to do so. Problem here
> > is that PVH can also be booted without firmware, in which case it
> > needs the hypervisor to have setup some sane initial MTRR state.
> >
> > The statement in the PVH document about initial MTRR state is vague
> > enough that allows Xen to boot into the guest with a minimal MTRR
> > state, that can for example not contain UC regions for the MMIO
> > regions of passed through devices, hence I think OVMF should be in
> > charge of creating a more complete MTRR state if possible.
> >
> > Is this something OVMF already has logic for?
>
> Well, there are some logic but it's for QEMU (and uses an interface that
> isn't available when running on Xen, fwcfg).
>
> The logic that was there for Xen HVM was very simple, a single set
> cache-write-back for the RAM, that's why I remove it (and because I'm
> not sure yet I figured out how to run the mtrr functions correctly in
> OVMF).
>
> I probably going to have to write a new logic which would rewrite the
> MTRR from scratch instead of relying on the existing setup.
>
> > Also accounting for the MMIO regions of devices?
>
> I'll have to dig deeper into OVMF codes, and PCI device handling. On
> HVM, we have a different logic than the one for QEMU, OVMF only scan
> what hvmloader have done instead of re-setup the pci devices. I'm
> probably missing other stuff.
MTRR setup it's always a PITA, I was hoping OVMF could manage to do
that based on the memory map plus scanning for devices and positioning
BARs, but if it gets the information from other side-channels it's
going to be more complicated.
Anyway, something to improve in the future in order to get rid of
hvmloader.
> > > diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> > > index cb7dd93ad6..3e33e7f414 100644
> > > --- a/OvmfPkg/XenPlatformPei/MemDetect.c
> > > +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> > > @@ -96,6 +96,47 @@ Q35TsegMbytesInitialization (
> > > mQ35TsegMbytes = ExtendedTsegMbytes;
> > > }
> > >
> > > +STATIC
> > > +UINT64
> > > +GetHighestSystemMemoryAddress (
> > > + BOOLEAN Below4gb
> > > + )
> > > +{
> > > + EFI_E820_ENTRY64 *E820Map;
> > > + UINT32 E820EntriesCount;
> > > + EFI_E820_ENTRY64 *Entry;
> > > + EFI_STATUS Status;
> > > + UINT32 Loop;
> > > + UINT64 HighestAddress;
> > > + UINT64 EntryEnd;
> > > +
> > > + HighestAddress = 0;
> > > +
> > > + Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> >
> > You could maybe initialize this as a global to avoid having to issue
> > a hypercall each time you need to get something from the memory map.
>
> That function does that, it only make the hypercall once. (The hypercall
> can only be made once anyway, the second time Xen doesn't return the
> map.)
Why? I'm looking at the implementation in Xen of XENMEM_memory_map and
I'm not sure I see how/why the hypercall can only be made once. AFAICT
you should be able to call XENMEM_memory_map multiple times without
issues, or else it's a bug somewhere.
> > > + ASSERT_EFI_ERROR (Status);
> > > +
> > > + for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> > > + Entry = E820Map + Loop;
> > > + EntryEnd = Entry->BaseAddr + Entry->Length;
> > > +
> > > + if (Entry->Type == EfiAcpiAddressRangeMemory &&
> > > + EntryEnd > HighestAddress) {
> > > +
> > > + if (Below4gb && (EntryEnd <= BASE_4GB)) {
> > > + HighestAddress = EntryEnd;
> > > + } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
> > > + HighestAddress = EntryEnd;
> > > + }
> > > + }
> > > + }
> > > +
> > > + //
> > > + // Round down the end address.
> > > + //
> > > + HighestAddress &= ~(UINT64)EFI_PAGE_MASK;
> > > +
> > > + return HighestAddress;
> >
> > You could do the rounding on the return statement.
>
> Yes, I think that can be done.
>
> > > +}
> > >
> > > UINT32
> > > GetSystemMemorySizeBelow4gb (
> > > @@ -105,6 +146,19 @@ GetSystemMemorySizeBelow4gb (
> > > UINT8 Cmos0x34;
> > > UINT8 Cmos0x35;
> > >
> > > + //
> > > + // In PVH case, there is no CMOS, we have to calculate the memory size
> > > + // from parsing the E820
> > > + //
> > > + if (XenPvhDetected ()) {
> >
> > IIRC on HVM you can also get the memory map from the hypercall, in
> > which case you could use the same code path for both HVM and PVH.
>
> I think that wouldn't work because in my experiment, the hypercall would
> only return the map the first time (at least on PVH). hvmloader already
> make the hypercall so OVMF can't.
OK, I'm not sure the reason for this, as I said above I think this is
a bug somewhere. You should be able to call XENMEM_memory_map multiple
times.
> On the other hand, XenGetE820Map() return an E820 map, it doesn't matter
> if it's the one passed by hvmloader, or the one we've got directly from
> Xen. So I guess we could ignore what hvmloader have written in the CMOS
Hm, I'm not sure hvmloader uploads a new memory map to Xen (using
XENMEM_set_memory_map) if it does any modifications to it. It should
certainly do it, so that the guest OS gets the same memory map from
the hypercall or from the firmware.
> and use the information in the e820 directly. But I think I let this
> change for future patch.
>
> > > + UINT64 HighestAddress;
> > > +
> > > + HighestAddress = GetHighestSystemMemoryAddress (TRUE);
> > > + ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);
> > > +
> > > + return HighestAddress;
> >
> > The name of the function here is GetSystemMemorySizeBelow4gb, but you
> > are returning the highest memory address in the range, is this
> > expected?
> >
> > ie: highest address != memory size
> >
> > On HVM there are quite some holes in the memory map, and nothing
> > guarantees there are no memory regions after the holes or non-RAM
> > regions.
>
> I think that's what is expected by caller of the function.
OK, the naming is slightly misleading, just wanted to make sure this
was the expected value.
> > > + }
> > > +
> > > //
> > > // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> > > // * CMOS(0x35) is the high byte
> > > diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
> > > index cbfd8058fc..62a2c3ed93 100644
> > > --- a/OvmfPkg/XenPlatformPei/Xen.c
> > > +++ b/OvmfPkg/XenPlatformPei/Xen.c
> > > @@ -279,6 +279,8 @@ XenPublishRamRegions (
> > > EFI_E820_ENTRY64 *E820Map;
> > > UINT32 E820EntriesCount;
> > > EFI_STATUS Status;
> > > + EFI_E820_ENTRY64 *Entry;
> > > + UINTN Index;
> > >
> > > DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
> > >
> > > @@ -287,26 +289,45 @@ XenPublishRamRegions (
> > > //
> > > E820EntriesCount = 0;
> > > Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> > > -
> > > ASSERT_EFI_ERROR (Status);
> > >
> > > - if (E820EntriesCount > 0) {
> > > - EFI_E820_ENTRY64 *Entry;
> > > - UINT32 Loop;
> > > + for (Index = 0; Index < E820EntriesCount; Index++) {
> > > + UINT64 Base;
> > > + UINT64 End;
> > >
> > > - for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> > > - Entry = E820Map + Loop;
> > > + Entry = &E820Map[Index];
> > >
> > > +
> > > + //
> > > + // Round up the start address, and round down the end address.
> > > + //
> > > + Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
> > > + End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
> > > +
> > > + switch (Entry->Type) {
> > > + case EfiAcpiAddressRangeMemory:
> > > + AddMemoryRangeHob (Base, End);
> > > + break;
> > > + case EfiAcpiAddressRangeACPI:
> > > + //
> > > + // Ignore, OVMF should read the ACPI tables and provide them to linux
> > > + // from a different location.
> >
> > Will OVMF also parse dynamic tables to check for references there?
>
> I haven't looked at what OVMF does with the ACPI tables, but Linux seems
> fine. I've compared the boot output of linux running as PVH vs booted
> via OVMF. Beside the location of the table been different, the number of
> table where the same, I don't remember other difference.
OK, what I find weird is that you seem to discard quite a lot of stuff
from the original memory map, and then reconstruct it afterwards I
assume?
It would seem safer to not discard regions from the memory map
provided to OVMF, and instead just build on top of it. I would expect
for example that OVMF will use some of the RAM regions on the memory
map, and it should likely turn those areas from RAM into reserved
regions.
> > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > //
> > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > - continue;
> > > + if (!XenHvmloaderDetected ()) {
> > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> >
> > This special casing for PVH looks weird, ideally we would like to use
> > the same code path, or else it should be explicitly mentioned why PVH
> > has diverging behaviour.
>
> I think hvmloader is the issue rather than PVH. Here is part of the
> "memory map" as found in hvmloader/config.h:
>
> /* Special BIOS mappings, etc. are allocated from here upwards... */
> #define RESERVED_MEMBASE 0xFC000000
> /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
>
> and hvmloader simply creates a single e820 reserved entry, from
> RESERVED_MEMBASE to the top of 4GB. It's probably too much.
But isn't this kind of dangerous? How can you assure future versions
of hvmloader won't use this space?
> If hvmloader only reserved
> ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> to special case hvmloader.
Could we look into getting this fixed in hvmloader then?
I think it's dangerous for OVMF to play such tricks with the memory
map.
> As far as I know 0xfee00000 isn't a special
> bios mapping, but something the hardware provides.
Yes, that's used by the lapic, so it's not specific to hvmloader.
> Anyway, thanks for the feedback, there's probably quite a bit to do to
> cleanup the memory stuff. I do think about one day running OVMF without
> running hvmloader first :-), but there's a bit more to do.
Sorry if some of my comments are out of place, I certainly know very
little about OVMF code base, or the Xen bits in it.
Running OVMF without hvmloader would be my end goal also if possible
:).
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-23 9:42 ` Roger Pau Monné
@ 2019-07-23 16:06 ` Anthony PERARD
2019-07-24 16:17 ` Anthony PERARD
1 sibling, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-23 16:06 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Tue, Jul 23, 2019 at 11:42:07AM +0200, Roger Pau Monné wrote:
> On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> > On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > You could maybe initialize this as a global to avoid having to issue
> > > a hypercall each time you need to get something from the memory map.
> >
> > That function does that, it only make the hypercall once. (The hypercall
> > can only be made once anyway, the second time Xen doesn't return the
> > map.)
>
> Why? I'm looking at the implementation in Xen of XENMEM_memory_map and
> I'm not sure I see how/why the hypercall can only be made once. AFAICT
> you should be able to call XENMEM_memory_map multiple times without
> issues, or else it's a bug somewhere.
:-(, I probably made a mistake when testing that. I tried again and
calling the hypercall serveral time gave the same result. Sorry for the
noise.
> > > > +}
> > > >
> > > > UINT32
> > > > GetSystemMemorySizeBelow4gb (
> > > > @@ -105,6 +146,19 @@ GetSystemMemorySizeBelow4gb (
> > > > UINT8 Cmos0x34;
> > > > UINT8 Cmos0x35;
> > > >
> > > > + //
> > > > + // In PVH case, there is no CMOS, we have to calculate the memory size
> > > > + // from parsing the E820
> > > > + //
> > > > + if (XenPvhDetected ()) {
> > >
> > > IIRC on HVM you can also get the memory map from the hypercall, in
> > > which case you could use the same code path for both HVM and PVH.
> >
> > I think that wouldn't work because in my experiment, the hypercall would
> > only return the map the first time (at least on PVH). hvmloader already
> > make the hypercall so OVMF can't.
>
> OK, I'm not sure the reason for this, as I said above I think this is
> a bug somewhere. You should be able to call XENMEM_memory_map multiple
> times.
>
> > On the other hand, XenGetE820Map() return an E820 map, it doesn't matter
> > if it's the one passed by hvmloader, or the one we've got directly from
> > Xen. So I guess we could ignore what hvmloader have written in the CMOS
>
> Hm, I'm not sure hvmloader uploads a new memory map to Xen (using
> XENMEM_set_memory_map) if it does any modifications to it. It should
> certainly do it, so that the guest OS gets the same memory map from
> the hypercall or from the firmware.
hvmloader doesn't call XENMEM_set_memory_map (I don't find that string
in the source code), also, I've tested again calling the get memory_map
hypercall in HVM guests and the e820 from hvmloader is different from
the one from the hypercall:
from hvmloader:
Type Mem - 00000000 -> 000A0000
Type Res - 000F0000 -> 00100000
Type Mem - 00100000 -> 3F6B3000
Type Res - FC000000 -> 100000000
from Xen:
Type Mem - 00100000 -> 3F800000
> > > > + switch (Entry->Type) {
> > > > + case EfiAcpiAddressRangeMemory:
> > > > + AddMemoryRangeHob (Base, End);
> > > > + break;
> > > > + case EfiAcpiAddressRangeACPI:
> > > > + //
> > > > + // Ignore, OVMF should read the ACPI tables and provide them to linux
> > > > + // from a different location.
> > >
> > > Will OVMF also parse dynamic tables to check for references there?
> >
> > I haven't looked at what OVMF does with the ACPI tables, but Linux seems
> > fine. I've compared the boot output of linux running as PVH vs booted
> > via OVMF. Beside the location of the table been different, the number of
> > table where the same, I don't remember other difference.
>
> OK, what I find weird is that you seem to discard quite a lot of stuff
> from the original memory map, and then reconstruct it afterwards I
> assume?
>
> It would seem safer to not discard regions from the memory map
> provided to OVMF, and instead just build on top of it. I would expect
OK, I'll add back the EfiAcpiAddressRangeACPI into the reserved regions.
> for example that OVMF will use some of the RAM regions on the memory
> map, and it should likely turn those areas from RAM into reserved
> regions.
>
> > > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > > //
> > > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > > - continue;
> > > > + if (!XenHvmloaderDetected ()) {
> > > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> > >
> > > This special casing for PVH looks weird, ideally we would like to use
> > > the same code path, or else it should be explicitly mentioned why PVH
> > > has diverging behaviour.
> >
> > I think hvmloader is the issue rather than PVH. Here is part of the
> > "memory map" as found in hvmloader/config.h:
> >
> > /* Special BIOS mappings, etc. are allocated from here upwards... */
> > #define RESERVED_MEMBASE 0xFC000000
> > /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> > #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> > #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> > #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
> >
> > and hvmloader simply creates a single e820 reserved entry, from
> > RESERVED_MEMBASE to the top of 4GB. It's probably too much.
>
> But isn't this kind of dangerous? How can you assure future versions
> of hvmloader won't use this space?
>
> > If hvmloader only reserved
> > ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> > to special case hvmloader.
>
> Could we look into getting this fixed in hvmloader then?
>
> I think it's dangerous for OVMF to play such tricks with the memory
> map.
It's not worse than before :), there's a lot more to cleanup :(.
I've left an hvmloader specific call
AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
which is outside of that XenPublishRamRegions() function. See:
https://lists.xenproject.org/archives/html/xen-devel/2019-07/msg00360.html
I probably need to remove that now and see if I can simply use
hvmloader's e820.
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-23 9:42 ` Roger Pau Monné
2019-07-23 16:06 ` Anthony PERARD
@ 2019-07-24 16:17 ` Anthony PERARD
2019-07-25 9:08 ` Roger Pau Monné
1 sibling, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-24 16:17 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Tue, Jul 23, 2019 at 11:42:07AM +0200, Roger Pau Monné wrote:
> On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> > On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > > //
> > > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > > - continue;
> > > > + if (!XenHvmloaderDetected ()) {
> > > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> > >
> > > This special casing for PVH looks weird, ideally we would like to use
> > > the same code path, or else it should be explicitly mentioned why PVH
> > > has diverging behaviour.
> >
> > I think hvmloader is the issue rather than PVH. Here is part of the
> > "memory map" as found in hvmloader/config.h:
> >
> > /* Special BIOS mappings, etc. are allocated from here upwards... */
> > #define RESERVED_MEMBASE 0xFC000000
> > /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> > #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> > #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> > #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
> >
> > and hvmloader simply creates a single e820 reserved entry, from
> > RESERVED_MEMBASE to the top of 4GB. It's probably too much.
>
> But isn't this kind of dangerous? How can you assure future versions
> of hvmloader won't use this space?
>
> > If hvmloader only reserved
> > ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> > to special case hvmloader.
>
> Could we look into getting this fixed in hvmloader then?
>
> I think it's dangerous for OVMF to play such tricks with the memory
> map.
>
> > As far as I know 0xfee00000 isn't a special
> > bios mapping, but something the hardware provides.
>
> Yes, that's used by the lapic, so it's not specific to hvmloader.
Right, I've got a closer look at that CpuDxe module, it wants the local
APIC memory mapped space to be "mapped IO", and that different than
"reserved".
So while parsing the e820 from hvmloader, instead of ignoring all
reserved region, I'm going to avoid adding the local apic memory mapped
space.
something like:
if (hvmloaderDetected())
Base = $(start of the e820 entry);
End = $(start of the e820 entry + size);
LocalApic = 0xfee00000;
if (Base < LocalApic && LocalApic < End) {
AddReservedMemoryRangeHob (Base, LocalApic, FALSE);
if (End > (LocalApic + SIZE_4KB)) {
AddReservedMemoryRangeHob (LocalApic + SIZE_4KB, End, FALSE);
}
}
}
Also, I will always add the 0xfee00000 as mapped IO, CpuDxe will not
complain as the region will be of the expected type.
I think with that change (and the other about the ACPI entries),
everything from the e820 table will be put into OVMF's memory map.
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-24 16:17 ` Anthony PERARD
@ 2019-07-25 9:08 ` Roger Pau Monné
2019-07-25 10:05 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-25 9:08 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Wed, Jul 24, 2019 at 05:17:59PM +0100, Anthony PERARD wrote:
> On Tue, Jul 23, 2019 at 11:42:07AM +0200, Roger Pau Monné wrote:
> > On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> > > On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > > > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > > > //
> > > > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > > > - continue;
> > > > > + if (!XenHvmloaderDetected ()) {
> > > > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> > > >
> > > > This special casing for PVH looks weird, ideally we would like to use
> > > > the same code path, or else it should be explicitly mentioned why PVH
> > > > has diverging behaviour.
> > >
> > > I think hvmloader is the issue rather than PVH. Here is part of the
> > > "memory map" as found in hvmloader/config.h:
> > >
> > > /* Special BIOS mappings, etc. are allocated from here upwards... */
> > > #define RESERVED_MEMBASE 0xFC000000
> > > /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> > > #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> > > #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> > > #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
> > >
> > > and hvmloader simply creates a single e820 reserved entry, from
> > > RESERVED_MEMBASE to the top of 4GB. It's probably too much.
> >
> > But isn't this kind of dangerous? How can you assure future versions
> > of hvmloader won't use this space?
> >
> > > If hvmloader only reserved
> > > ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> > > to special case hvmloader.
> >
> > Could we look into getting this fixed in hvmloader then?
> >
> > I think it's dangerous for OVMF to play such tricks with the memory
> > map.
> >
> > > As far as I know 0xfee00000 isn't a special
> > > bios mapping, but something the hardware provides.
> >
> > Yes, that's used by the lapic, so it's not specific to hvmloader.
>
> Right, I've got a closer look at that CpuDxe module, it wants the local
> APIC memory mapped space to be "mapped IO", and that different than
> "reserved".
>
> So while parsing the e820 from hvmloader, instead of ignoring all
> reserved region, I'm going to avoid adding the local apic memory mapped
> space.
>
> something like:
> if (hvmloaderDetected())
I don't think you need to gate this on hvmloader being used, while
it's true that PVH memory map doesn't contain such reserved memory
region ATM I don't see any harm in doing this for PVH also.
> Base = $(start of the e820 entry);
> End = $(start of the e820 entry + size);
> LocalApic = 0xfee00000;
> if (Base < LocalApic && LocalApic < End) {
> AddReservedMemoryRangeHob (Base, LocalApic, FALSE);
> if (End > (LocalApic + SIZE_4KB)) {
The range is actually from 0xfee00000 to 0xfeefffff (2MB), so you
likely want to make sure non of this is added as reserved?
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-25 9:08 ` Roger Pau Monné
@ 2019-07-25 10:05 ` Anthony PERARD
2019-07-25 11:03 ` Roger Pau Monné
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-25 10:05 UTC (permalink / raw)
To: Roger Pau Monné
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Thu, Jul 25, 2019 at 11:08:29AM +0200, Roger Pau Monné wrote:
> On Wed, Jul 24, 2019 at 05:17:59PM +0100, Anthony PERARD wrote:
> > On Tue, Jul 23, 2019 at 11:42:07AM +0200, Roger Pau Monné wrote:
> > > On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> > > > On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > > > > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > > > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > > > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > > > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > > > > //
> > > > > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > > > > - continue;
> > > > > > + if (!XenHvmloaderDetected ()) {
> > > > > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> > > > >
> > > > > This special casing for PVH looks weird, ideally we would like to use
> > > > > the same code path, or else it should be explicitly mentioned why PVH
> > > > > has diverging behaviour.
> > > >
> > > > I think hvmloader is the issue rather than PVH. Here is part of the
> > > > "memory map" as found in hvmloader/config.h:
> > > >
> > > > /* Special BIOS mappings, etc. are allocated from here upwards... */
> > > > #define RESERVED_MEMBASE 0xFC000000
> > > > /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> > > > #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> > > > #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> > > > #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
> > > >
> > > > and hvmloader simply creates a single e820 reserved entry, from
> > > > RESERVED_MEMBASE to the top of 4GB. It's probably too much.
> > >
> > > But isn't this kind of dangerous? How can you assure future versions
> > > of hvmloader won't use this space?
> > >
> > > > If hvmloader only reserved
> > > > ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> > > > to special case hvmloader.
> > >
> > > Could we look into getting this fixed in hvmloader then?
> > >
> > > I think it's dangerous for OVMF to play such tricks with the memory
> > > map.
> > >
> > > > As far as I know 0xfee00000 isn't a special
> > > > bios mapping, but something the hardware provides.
> > >
> > > Yes, that's used by the lapic, so it's not specific to hvmloader.
> >
> > Right, I've got a closer look at that CpuDxe module, it wants the local
> > APIC memory mapped space to be "mapped IO", and that different than
> > "reserved".
> >
> > So while parsing the e820 from hvmloader, instead of ignoring all
> > reserved region, I'm going to avoid adding the local apic memory mapped
> > space.
> >
> > something like:
> > if (hvmloaderDetected())
>
> I don't think you need to gate this on hvmloader being used, while
> it's true that PVH memory map doesn't contain such reserved memory
> region ATM I don't see any harm in doing this for PVH also.
Ok.
> > Base = $(start of the e820 entry);
> > End = $(start of the e820 entry + size);
> > LocalApic = 0xfee00000;
> > if (Base < LocalApic && LocalApic < End) {
> > AddReservedMemoryRangeHob (Base, LocalApic, FALSE);
> > if (End > (LocalApic + SIZE_4KB)) {
>
> The range is actually from 0xfee00000 to 0xfeefffff (2MB), so you
> likely want to make sure non of this is added as reserved?
You mean 1MB, right ? :-). I've try to find out in the Intel manual why
it would be 1MB and couldn't find that, but on the other hand the
initialisation code for OVMF running on QEMU does also reserve 1MB for
the local apic. So I'll change to 1MB.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection
2019-07-25 10:05 ` Anthony PERARD
@ 2019-07-25 11:03 ` Roger Pau Monné
0 siblings, 0 replies; 90+ messages in thread
From: Roger Pau Monné @ 2019-07-25 11:03 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Andrew Cooper
On Thu, Jul 25, 2019 at 11:05:34AM +0100, Anthony PERARD wrote:
> On Thu, Jul 25, 2019 at 11:08:29AM +0200, Roger Pau Monné wrote:
> > On Wed, Jul 24, 2019 at 05:17:59PM +0100, Anthony PERARD wrote:
> > > On Tue, Jul 23, 2019 at 11:42:07AM +0200, Roger Pau Monné wrote:
> > > > On Mon, Jul 22, 2019 at 03:53:19PM +0100, Anthony PERARD wrote:
> > > > > On Mon, Jul 15, 2019 at 04:15:21PM +0200, Roger Pau Monné wrote:
> > > > > > On Thu, Jul 04, 2019 at 03:42:22PM +0100, Anthony PERARD wrote:
> > > > > > > + // error message: CpuDxe: IntersectMemoryDescriptor:
> > > > > > > + // desc [FC000000, 100000000) type 1 cap 8700000000026001
> > > > > > > + // conflicts with aperture [FEE00000, FEE01000) cap 1
> > > > > > > //
> > > > > > > - if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > > > > > > - continue;
> > > > > > > + if (!XenHvmloaderDetected ()) {
> > > > > > > + AddReservedMemoryBaseSizeHob (Base, End - Base, FALSE);
> > > > > >
> > > > > > This special casing for PVH looks weird, ideally we would like to use
> > > > > > the same code path, or else it should be explicitly mentioned why PVH
> > > > > > has diverging behaviour.
> > > > >
> > > > > I think hvmloader is the issue rather than PVH. Here is part of the
> > > > > "memory map" as found in hvmloader/config.h:
> > > > >
> > > > > /* Special BIOS mappings, etc. are allocated from here upwards... */
> > > > > #define RESERVED_MEMBASE 0xFC000000
> > > > > /* NB. ACPI_INFO_PHYSICAL_ADDRESS *MUST* match definition in acpi/dsdt.asl! */
> > > > > #define ACPI_INFO_PHYSICAL_ADDRESS 0xFC000000
> > > > > #define RESERVED_MEMORY_DYNAMIC_START 0xFC001000
> > > > > #define RESERVED_MEMORY_DYNAMIC_END 0xFE000000
> > > > >
> > > > > and hvmloader simply creates a single e820 reserved entry, from
> > > > > RESERVED_MEMBASE to the top of 4GB. It's probably too much.
> > > >
> > > > But isn't this kind of dangerous? How can you assure future versions
> > > > of hvmloader won't use this space?
> > > >
> > > > > If hvmloader only reserved
> > > > > ACPI_INFO_PHYSICAL_ADDRESS-RESERVED_MEMORY_DYNAMIC_END, I might not have
> > > > > to special case hvmloader.
> > > >
> > > > Could we look into getting this fixed in hvmloader then?
> > > >
> > > > I think it's dangerous for OVMF to play such tricks with the memory
> > > > map.
> > > >
> > > > > As far as I know 0xfee00000 isn't a special
> > > > > bios mapping, but something the hardware provides.
> > > >
> > > > Yes, that's used by the lapic, so it's not specific to hvmloader.
> > >
> > > Right, I've got a closer look at that CpuDxe module, it wants the local
> > > APIC memory mapped space to be "mapped IO", and that different than
> > > "reserved".
> > >
> > > So while parsing the e820 from hvmloader, instead of ignoring all
> > > reserved region, I'm going to avoid adding the local apic memory mapped
> > > space.
> > >
> > > something like:
> > > if (hvmloaderDetected())
> >
> > I don't think you need to gate this on hvmloader being used, while
> > it's true that PVH memory map doesn't contain such reserved memory
> > region ATM I don't see any harm in doing this for PVH also.
>
> Ok.
>
> > > Base = $(start of the e820 entry);
> > > End = $(start of the e820 entry + size);
> > > LocalApic = 0xfee00000;
> > > if (Base < LocalApic && LocalApic < End) {
> > > AddReservedMemoryRangeHob (Base, LocalApic, FALSE);
> > > if (End > (LocalApic + SIZE_4KB)) {
> >
> > The range is actually from 0xfee00000 to 0xfeefffff (2MB), so you
> > likely want to make sure non of this is added as reserved?
>
> You mean 1MB, right ? :-).
D'oh, yes :).
> I've try to find out in the Intel manual why
> it would be 1MB and couldn't find that, but on the other hand the
> initialisation code for OVMF running on QEMU does also reserve 1MB for
> the local apic. So I'll change to 1MB.
It's the Interrupt Address Range, which contains the mmio lapic
registers and the mmio region where devices write in order to signal
interrupts to the apic (used as the address field for MSI(-X)).
Thanks, Roger.
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 25/35] OvmfPkg/XenPlatformPei: Reserve VGA memory region, to boot Linux
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (23 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 24/35] OvmfPkg/XenPlatformPei: Rework memory detection Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 26/35] OvmfPkg/XenPlatformPei: Ignore missing PCI Host Bridge on Xen PVH Anthony PERARD
` (12 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Linux panic if the VGA region isn't reserved.
When Linux is booted on EFI system, it expects the memory at 0xa0000 to
_not_ be conventional memory. Otherwise a variable isn't initialised
properly and Linux panic when a virtual console/terminal is asked to be
created.
See for more detail:
https://lists.xenproject.org/archives/html/xen-devel/2019-03/msg02139.html
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix commit message
OvmfPkg/XenPlatformPei/Xen.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 62a2c3ed93..9866b7c212 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -291,6 +291,12 @@ XenPublishRamRegions (
Status = XenGetE820Map (&E820Map, &E820EntriesCount);
ASSERT_EFI_ERROR (Status);
+ AddMemoryBaseSizeHob (0, 0xA0000);
+ //
+ // Video memory + Legacy BIOS region, to allow Linux to boot.
+ //
+ AddReservedMemoryBaseSizeHob (0xA0000, BASE_1MB - 0xA0000, TRUE);
+
for (Index = 0; Index < E820EntriesCount; Index++) {
UINT64 Base;
UINT64 End;
@@ -304,6 +310,16 @@ XenPublishRamRegions (
Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
+ //
+ // Ignore the first 1MB, this is handled before the loop.
+ //
+ if (Base < BASE_1MB) {
+ Base = BASE_1MB;
+ }
+ if (Base >= End) {
+ continue;
+ }
+
switch (Entry->Type) {
case EfiAcpiAddressRangeMemory:
AddMemoryRangeHob (Base, End);
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 26/35] OvmfPkg/XenPlatformPei: Ignore missing PCI Host Bridge on Xen PVH
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (24 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 25/35] OvmfPkg/XenPlatformPei: Reserve VGA memory region, to boot Linux Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-08 15:31 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 27/35] OvmfPkg/XenPlatformLib: Cache result for XenDetected Anthony PERARD
` (11 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
When the device ID of the host bridge is unknown, check if we are
running as a PVH guest as there is no PCI bus in that case.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- Remove use of XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID, and simply don't set
PcdOvmfHostBridgePciDevId.
v2:
- Use new XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID macro
OvmfPkg/XenPlatformPei/Platform.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
index 52f6048ca4..b7fc30d2ee 100644
--- a/OvmfPkg/XenPlatformPei/Platform.c
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -272,6 +272,12 @@ MiscInitialization (
AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
break;
default:
+ if (XenPvhDetected ()) {
+ //
+ // There is no PCI bus in this case
+ //
+ return;
+ }
DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
__FUNCTION__, mHostBridgeDevId));
ASSERT (FALSE);
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 26/35] OvmfPkg/XenPlatformPei: Ignore missing PCI Host Bridge on Xen PVH
2019-07-04 14:42 ` [PATCH v3 26/35] OvmfPkg/XenPlatformPei: Ignore missing PCI Host Bridge on Xen PVH Anthony PERARD
@ 2019-07-08 15:31 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-08 15:31 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> When the device ID of the host bridge is unknown, check if we are
> running as a PVH guest as there is no PCI bus in that case.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - Remove use of XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID, and simply don't set
> PcdOvmfHostBridgePciDevId.
>
> v2:
> - Use new XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID macro
>
> OvmfPkg/XenPlatformPei/Platform.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
> index 52f6048ca4..b7fc30d2ee 100644
> --- a/OvmfPkg/XenPlatformPei/Platform.c
> +++ b/OvmfPkg/XenPlatformPei/Platform.c
> @@ -272,6 +272,12 @@ MiscInitialization (
> AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
> break;
> default:
> + if (XenPvhDetected ()) {
> + //
> + // There is no PCI bus in this case
> + //
> + return;
> + }
> DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> __FUNCTION__, mHostBridgeDevId));
> ASSERT (FALSE);
>
Acked-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 27/35] OvmfPkg/XenPlatformLib: Cache result for XenDetected
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (25 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 26/35] OvmfPkg/XenPlatformPei: Ignore missing PCI Host Bridge on Xen PVH Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 9:31 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 28/35] OvmfPkg/PlatformBootManagerLib: Use XenDetected from XenPlatformLib Anthony PERARD
` (10 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
We are going to replace XenDetected() implementation in
PlatformBootManagerLib by the one in XenPlatformLib.
PlatformBootManagerLib's implementation does cache the result of
GetFirstGuidHob(), so we do something similar in XenPlatformLib.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- new patch
.../Library/XenPlatformLib/XenPlatformLib.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
index 6f27cbffa8..b5257b0c97 100644
--- a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
+++ b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
@@ -26,13 +26,25 @@ XenGetInfoHOB (
)
{
EFI_HOB_GUID_TYPE *GuidHob;
+ STATIC BOOLEAN Cached = FALSE;
+ STATIC EFI_XEN_INFO *XenInfo;
+
+ //
+ // Return the cached result for the benefit of XenDetected that can be
+ // called many times.
+ //
+ if (Cached) {
+ return XenInfo;
+ }
GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
if (GuidHob == NULL) {
- return NULL;
+ XenInfo = NULL;
+ } else {
+ XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
}
-
- return (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
+ Cached = TRUE;
+ return XenInfo;
}
/**
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 27/35] OvmfPkg/XenPlatformLib: Cache result for XenDetected
2019-07-04 14:42 ` [PATCH v3 27/35] OvmfPkg/XenPlatformLib: Cache result for XenDetected Anthony PERARD
@ 2019-07-10 9:31 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 9:31 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> We are going to replace XenDetected() implementation in
> PlatformBootManagerLib by the one in XenPlatformLib.
> PlatformBootManagerLib's implementation does cache the result of
> GetFirstGuidHob(), so we do something similar in XenPlatformLib.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - new patch
>
> .../Library/XenPlatformLib/XenPlatformLib.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
> index 6f27cbffa8..b5257b0c97 100644
> --- a/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
> +++ b/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.c
> @@ -26,13 +26,25 @@ XenGetInfoHOB (
> )
> {
> EFI_HOB_GUID_TYPE *GuidHob;
> + STATIC BOOLEAN Cached = FALSE;
> + STATIC EFI_XEN_INFO *XenInfo;
(1) The alignment of the variable names is weird. The above is neither
condensed nor precisely aligned. Please pick one:
EFI_HOB_GUID_TYPE *GuidHob;
STATIC BOOLEAN Cached = FALSE;
STATIC EFI_XEN_INFO *XenInfo;
or
EFI_HOB_GUID_TYPE *GuidHob;
STATIC BOOLEAN Cached = FALSE;
STATIC EFI_XEN_INFO *XenInfo;
(The 2nd form is preferred in edk2.)
> +
> + //
> + // Return the cached result for the benefit of XenDetected that can be
> + // called many times.
> + //
> + if (Cached) {
> + return XenInfo;
> + }
>
> GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
> if (GuidHob == NULL) {
> - return NULL;
> + XenInfo = NULL;
> + } else {
> + XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> }
> -
> - return (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
> + Cached = TRUE;
> + return XenInfo;
> }
>
> /**
>
This will work fine in DXE modules (and by the end of the series, only
DXE modules use XenPlatformLib -- AcpiPlatformDxe, XenIoPvhDxe, and
PlatformBootManagerLib, which is only linked into DXE modules).
With (1) fixed:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 28/35] OvmfPkg/PlatformBootManagerLib: Use XenDetected from XenPlatformLib
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (26 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 27/35] OvmfPkg/XenPlatformLib: Cache result for XenDetected Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 9:45 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 29/35] OvmfPkg/PlatformBootManagerLib: Handle the absence of PCI bus on Xen PVH Anthony PERARD
` (9 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Replace the XenDetected() implementation by the one from
XenPlatformLib.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- new patch
.../PlatformBootManagerLib.inf | 1 +
.../PlatformBootManagerLib/BdsPlatform.c | 33 +------------------
2 files changed, 2 insertions(+), 32 deletions(-)
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index 060a3ab4c5..b2d3b4fb4d 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -54,6 +54,7 @@ [LibraryClasses]
UefiLib
PlatformBmPrintScLib
Tcg2PhysicalPresenceLib
+ XenPlatformLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 797731a41c..e32969e63e 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -12,6 +12,7 @@
#include <Protocol/FirmwareVolume2.h>
#include <Library/PlatformBmPrintScLib.h>
#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/XenPlatformLib.h>
//
@@ -1225,38 +1226,6 @@ PciAcpiInitialization (
IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
}
-/**
- This function detects if OVMF is running on Xen.
-
-**/
-STATIC
-BOOLEAN
-XenDetected (
- VOID
- )
-{
- EFI_HOB_GUID_TYPE *GuidHob;
- STATIC INTN FoundHob = -1;
-
- if (FoundHob == 0) {
- return FALSE;
- } else if (FoundHob == 1) {
- return TRUE;
- }
-
- //
- // See if a XenInfo HOB is available
- //
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
- if (GuidHob == NULL) {
- FoundHob = 0;
- return FALSE;
- }
-
- FoundHob = 1;
- return TRUE;
-}
-
EFI_STATUS
EFIAPI
ConnectRecursivelyIfPciMassStorage (
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 28/35] OvmfPkg/PlatformBootManagerLib: Use XenDetected from XenPlatformLib
2019-07-04 14:42 ` [PATCH v3 28/35] OvmfPkg/PlatformBootManagerLib: Use XenDetected from XenPlatformLib Anthony PERARD
@ 2019-07-10 9:45 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 9:45 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> Replace the XenDetected() implementation by the one from
> XenPlatformLib.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - new patch
>
> .../PlatformBootManagerLib.inf | 1 +
> .../PlatformBootManagerLib/BdsPlatform.c | 33 +------------------
> 2 files changed, 2 insertions(+), 32 deletions(-)
>
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index 060a3ab4c5..b2d3b4fb4d 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -54,6 +54,7 @@ [LibraryClasses]
> UefiLib
> PlatformBmPrintScLib
> Tcg2PhysicalPresenceLib
> + XenPlatformLib
>
> [Pcd]
> gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index 797731a41c..e32969e63e 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -12,6 +12,7 @@
> #include <Protocol/FirmwareVolume2.h>
> #include <Library/PlatformBmPrintScLib.h>
> #include <Library/Tcg2PhysicalPresenceLib.h>
> +#include <Library/XenPlatformLib.h>
>
>
> //
> @@ -1225,38 +1226,6 @@ PciAcpiInitialization (
> IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
> }
>
> -/**
> - This function detects if OVMF is running on Xen.
> -
> -**/
> -STATIC
> -BOOLEAN
> -XenDetected (
> - VOID
> - )
> -{
> - EFI_HOB_GUID_TYPE *GuidHob;
> - STATIC INTN FoundHob = -1;
> -
> - if (FoundHob == 0) {
> - return FALSE;
> - } else if (FoundHob == 1) {
> - return TRUE;
> - }
> -
> - //
> - // See if a XenInfo HOB is available
> - //
> - GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
> - if (GuidHob == NULL) {
> - FoundHob = 0;
> - return FALSE;
> - }
> -
> - FoundHob = 1;
> - return TRUE;
> -}
> -
> EFI_STATUS
> EFIAPI
> ConnectRecursivelyIfPciMassStorage (
>
Is it possible to clean up the remaining code a bit more, such as:
(1) removing
#include <Guid/XenInfo.h>
from "BdsPlatform.c",
(2) removing "gEfiXenInfoGuid" from [Guids] in "PlatformBootManagerLib.inf"?
With those:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 29/35] OvmfPkg/PlatformBootManagerLib: Handle the absence of PCI bus on Xen PVH
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (27 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 28/35] OvmfPkg/PlatformBootManagerLib: Use XenDetected from XenPlatformLib Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 9:50 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 30/35] OvmfPkg/OvmfXen: Override PcdFSBClock to Xen vLAPIC timer frequency Anthony PERARD
` (8 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
When running in a Xen PVH guest, there's nothing to do in
PciAcpiInitialization() because there isn't any PCI bus. When the Host
Bridge DID isn't recognised, simply continue. (The value of
PcdOvmfHostBridgePciDevId would be 0 because it isn't set.)
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- Instead of checking for a false value,
XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID, simply check if we are running xen
when the HostBridge device ID isn't recognised.
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index e32969e63e..9ae590293a 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1209,6 +1209,12 @@ PciAcpiInitialization (
PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
break;
default:
+ if (XenDetected ()) {
+ //
+ // There is no PCI bus in this case.
+ //
+ return;
+ }
DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
__FUNCTION__, mHostBridgeDevId));
ASSERT (FALSE);
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 29/35] OvmfPkg/PlatformBootManagerLib: Handle the absence of PCI bus on Xen PVH
2019-07-04 14:42 ` [PATCH v3 29/35] OvmfPkg/PlatformBootManagerLib: Handle the absence of PCI bus on Xen PVH Anthony PERARD
@ 2019-07-10 9:50 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 9:50 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> When running in a Xen PVH guest, there's nothing to do in
> PciAcpiInitialization() because there isn't any PCI bus. When the Host
> Bridge DID isn't recognised, simply continue. (The value of
> PcdOvmfHostBridgePciDevId would be 0 because it isn't set.)
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - Instead of checking for a false value,
> XEN_PVH_PCI_HOST_BRIDGE_DEVICE_ID, simply check if we are running xen
> when the HostBridge device ID isn't recognised.
>
> OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index e32969e63e..9ae590293a 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -1209,6 +1209,12 @@ PciAcpiInitialization (
> PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
> break;
> default:
> + if (XenDetected ()) {
> + //
> + // There is no PCI bus in this case.
> + //
> + return;
> + }
> DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> __FUNCTION__, mHostBridgeDevId));
> ASSERT (FALSE);
>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 30/35] OvmfPkg/OvmfXen: Override PcdFSBClock to Xen vLAPIC timer frequency
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (28 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 29/35] OvmfPkg/PlatformBootManagerLib: Handle the absence of PCI bus on Xen PVH Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 31/35] OvmfPkg/OvmfXen: Introduce XenTimerDxe Anthony PERARD
` (7 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
PcdFSBClock is used by SecPeiDxeTimerLibCpu, the TimerLib
implementation. It will also be used by XenTimerDxe. Override
PcdFSBClock to match Xen vLAPIC timer frequency.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- expand commit message body to be standalone
OvmfPkg/OvmfXen.dsc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 68d82da7aa..bc6b6602c6 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -439,6 +439,9 @@ [PcdsFixedAtBuild]
# Point to the MdeModulePkg/Application/UiApp/UiApp.inf
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+ ## Xen vlapic's frequence is 100 MHz
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|100000000
+
################################################################################
#
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 31/35] OvmfPkg/OvmfXen: Introduce XenTimerDxe
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (29 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 30/35] OvmfPkg/OvmfXen: Override PcdFSBClock to Xen vLAPIC timer frequency Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 10:12 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
` (6 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
"PcAtChipsetPkg/8254TimerDxe" is replaced with a Xen-specific
EFI_TIMER_ARCH_PROTOCOL implementation. Also remove
8259InterruptControllerDxe as it is not used anymore.
This Timer uses the local APIC timer as time source as it can work on
both a Xen PVH guest and an HVM one.
Based on the "PcAtChipsetPkg/8254TimerDxe" implementation.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- rebased, SPDX, copyright
v2:
- Use InitializeApicTimer instead of WriteLocalApicReg
- rework comments (remove many that don't apply)
- remove unused includes, and libs
- have a macro to the timervector.
- cleanup, copyright
- rework calculation of TimerCount, value to be use by the APIC timer
- check for overflow of TimerPeriod, with the apic timer, the period can
be up to about 42s on Xen (or even higher by changing the DivideValue).
OvmfPkg/OvmfXen.dsc | 3 +-
OvmfPkg/OvmfXen.fdf | 3 +-
OvmfPkg/XenTimerDxe/XenTimerDxe.inf | 42 ++++
OvmfPkg/XenTimerDxe/XenTimerDxe.h | 177 ++++++++++++++
OvmfPkg/XenTimerDxe/XenTimerDxe.c | 355 ++++++++++++++++++++++++++++
5 files changed, 576 insertions(+), 4 deletions(-)
create mode 100644 OvmfPkg/XenTimerDxe/XenTimerDxe.inf
create mode 100644 OvmfPkg/XenTimerDxe/XenTimerDxe.h
create mode 100644 OvmfPkg/XenTimerDxe/XenTimerDxe.c
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index bc6b6602c6..1ecae3fb45 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -547,10 +547,9 @@ [Components]
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
- OvmfPkg/8259InterruptControllerDxe/8259.inf
+ OvmfPkg/XenTimerDxe/XenTimerDxe.inf
UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
UefiCpuPkg/CpuDxe/CpuDxe.inf
- OvmfPkg/8254TimerDxe/8254Timer.inf
OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 49997fee9b..fa0830a324 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -298,10 +298,9 @@ [FV.DXEFV]
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
-INF OvmfPkg/8259InterruptControllerDxe/8259.inf
+INF OvmfPkg/XenTimerDxe/XenTimerDxe.inf
INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
INF UefiCpuPkg/CpuDxe/CpuDxe.inf
-INF OvmfPkg/8254TimerDxe/8254Timer.inf
INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/OvmfPkg/XenTimerDxe/XenTimerDxe.inf b/OvmfPkg/XenTimerDxe/XenTimerDxe.inf
new file mode 100644
index 0000000000..add1d01bbf
--- /dev/null
+++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.inf
@@ -0,0 +1,42 @@
+## @file
+# Local APIC timer driver that provides Timer Arch protocol.
+#
+# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = XenTimerDxe
+ FILE_GUID = 52fe8196-f9de-4d07-b22f-51f77a0e7c41
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = TimerDriverInitialize
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ BaseLib
+ DebugLib
+ UefiDriverEntryPoint
+ LocalApicLib
+
+[Sources]
+ XenTimerDxe.h
+ XenTimerDxe.c
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## CONSUMES
+ gEfiTimerArchProtocolGuid ## PRODUCES
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
+[Depex]
+ gEfiCpuArchProtocolGuid
diff --git a/OvmfPkg/XenTimerDxe/XenTimerDxe.h b/OvmfPkg/XenTimerDxe/XenTimerDxe.h
new file mode 100644
index 0000000000..e0a3d95fd0
--- /dev/null
+++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.h
@@ -0,0 +1,177 @@
+/** @file
+ Private data structures
+
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2019, Citrix Systems, Inc.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/Timer.h>
+
+#include <Register/LocalApic.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PcdLib.h>
+
+// The default timer tick duration is set to 10 ms = 100000 100 ns units
+//
+#define DEFAULT_TIMER_TICK_DURATION 100000
+
+//
+// The Timer Vector use for interrupt
+//
+#define LOCAL_APIC_TIMER_VECTOR 32
+
+//
+// Function Prototypes
+//
+/**
+ Initialize the Timer Architectural Protocol driver
+
+ @param ImageHandle ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Timer Architectural Protocol created
+ @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver.
+ @retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+/**
+
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param NotifyFunction The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+ @retval EFI_SUCCESS The timer period was changed.
+ @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
+ @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_TIMER_NOTIFY NotifyFunction
+ )
+;
+
+/**
+
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+ @retval EFI_SUCCESS The timer period was changed.
+ @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
+ @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod
+ )
+;
+
+/**
+
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
+ 0 is returned, then the timer is currently disabled.
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+;
+
+/**
+
+ This function generates a soft timer interrupt. If the platform does not support soft
+ timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+ If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+ service, then a soft timer interrupt will be generated. If the timer interrupt is
+ enabled when this service is called, then the registered handler will be invoked. The
+ registered handler should not be able to distinguish a hardware-generated timer
+ interrupt from a software-generated timer interrupt.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The soft timer interrupt was generated.
+ @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+ IN EFI_TIMER_ARCH_PROTOCOL *This
+ )
+;
+
+#endif
diff --git a/OvmfPkg/XenTimerDxe/XenTimerDxe.c b/OvmfPkg/XenTimerDxe/XenTimerDxe.c
new file mode 100644
index 0000000000..9f9e04766c
--- /dev/null
+++ b/OvmfPkg/XenTimerDxe/XenTimerDxe.c
@@ -0,0 +1,355 @@
+/** @file
+ Timer Architectural Protocol as defined in the DXE CIS
+
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2019, Citrix Systems, Inc.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "XenTimerDxe.h"
+
+//
+// The handle onto which the Timer Architectural Protocol will be installed
+//
+EFI_HANDLE mTimerHandle = NULL;
+
+//
+// The Timer Architectural Protocol that this driver produces
+//
+EFI_TIMER_ARCH_PROTOCOL mTimer = {
+ TimerDriverRegisterHandler,
+ TimerDriverSetTimerPeriod,
+ TimerDriverGetTimerPeriod,
+ TimerDriverGenerateSoftInterrupt
+};
+
+//
+// Pointer to the CPU Architectural Protocol instance
+//
+EFI_CPU_ARCH_PROTOCOL *mCpu;
+
+//
+// The notification function to call on every timer interrupt.
+// A bug in the compiler prevents us from initializing this here.
+//
+EFI_TIMER_NOTIFY mTimerNotifyFunction;
+
+//
+// The current period of the timer interrupt
+//
+volatile UINT64 mTimerPeriod = 0;
+
+//
+// Worker Functions
+//
+/**
+ Interrupt Handler.
+
+ @param InterruptType The type of interrupt that occurred
+ @param SystemContext A pointer to the system context when the interrupt occurred
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ EFI_TPL OriginalTPL;
+
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ SendApicEoi();
+
+ if (mTimerNotifyFunction != NULL) {
+ //
+ // @bug : This does not handle missed timer interrupts
+ //
+ mTimerNotifyFunction (mTimerPeriod);
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+
+ This function registers the handler NotifyFunction so it is called every time
+ the timer interrupt fires. It also passes the amount of time since the last
+ handler call to the NotifyFunction. If NotifyFunction is NULL, then the
+ handler is unregistered. If the handler is registered, then EFI_SUCCESS is
+ returned. If the CPU does not support registering a timer interrupt handler,
+ then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
+ when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+ If an attempt is made to unregister a handler when a handler is not registered,
+ then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
+ register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+ is returned.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param NotifyFunction The function to call when a timer interrupt fires. This
+ function executes at TPL_HIGH_LEVEL. The DXE Core will
+ register a handler for the timer interrupt, so it can know
+ how much time has passed. This information is used to
+ signal timer based events. NULL will unregister the handler.
+
+ @retval EFI_SUCCESS The timer handler was registered.
+ @retval EFI_UNSUPPORTED The platform does not support timer interrupts.
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
+ registered.
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+ previously registered.
+ @retval EFI_DEVICE_ERROR The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_TIMER_NOTIFY NotifyFunction
+ )
+{
+ //
+ // Check for invalid parameters
+ //
+ if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ mTimerNotifyFunction = NotifyFunction;
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+ @retval EFI_SUCCESS The timer period was changed.
+ @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
+ @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod
+ )
+{
+ UINT64 TimerCount;
+ UINT32 TimerFrequency;
+ UINTN DivideValue = 1;
+
+ if (TimerPeriod == 0) {
+ //
+ // Disable timer interrupt for a TimerPeriod of 0
+ //
+ DisableApicTimerInterrupt();
+ } else {
+ TimerFrequency = PcdGet32(PcdFSBClock) / DivideValue;
+
+ //
+ // Convert TimerPeriod into local APIC counts
+ //
+ // TimerPeriod is in 100ns
+ // TimerPeriod/10000000 will be in seconds.
+ TimerCount = DivU64x32 (MultU64x32 (TimerPeriod, TimerFrequency),
+ 10000000);
+
+ // Check for overflow
+ if (TimerCount > MAX_UINT32) {
+ TimerCount = MAX_UINT32;
+ /* TimerPeriod = (MAX_UINT32 / TimerFrequency) * 10000000; */
+ TimerPeriod = 429496730;
+ }
+
+ //
+ // Program the timer with the new count value
+ //
+ InitializeApicTimer(DivideValue, TimerCount, TRUE, LOCAL_APIC_TIMER_VECTOR);
+
+ //
+ // Enable timer interrupt
+ //
+ EnableApicTimerInterrupt();
+ }
+ //
+ // Save the new timer period
+ //
+ mTimerPeriod = TimerPeriod;
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
+ 0 is returned, then the timer is currently disabled.
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+{
+ if (TimerPeriod == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerPeriod = mTimerPeriod;
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function generates a soft timer interrupt. If the platform does not support soft
+ timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+ If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+ service, then a soft timer interrupt will be generated. If the timer interrupt is
+ enabled when this service is called, then the registered handler will be invoked. The
+ registered handler should not be able to distinguish a hardware-generated timer
+ interrupt from a software-generated timer interrupt.
+
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The soft timer interrupt was generated.
+ @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+ IN EFI_TIMER_ARCH_PROTOCOL *This
+ )
+{
+ EFI_TPL OriginalTPL;
+
+ if (GetApicTimerInterruptState()) {
+ //
+ // Invoke the registered handler
+ //
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ if (mTimerNotifyFunction != NULL) {
+ //
+ // @bug : This does not handle missed timer interrupts
+ //
+ mTimerNotifyFunction (mTimerPeriod);
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the Timer Architectural Protocol driver
+
+ @param ImageHandle ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Timer Architectural Protocol created
+ @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver.
+ @retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize the pointer to our notify function.
+ //
+ mTimerNotifyFunction = NULL;
+
+ //
+ // Make sure the Timer Architectural Protocol is not already installed in the system
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
+
+ //
+ // Find the CPU architectural protocol.
+ //
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Force the timer to be disabled
+ //
+ Status = TimerDriverSetTimerPeriod (&mTimer, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install interrupt handler for Local APIC Timer
+ //
+ Status = mCpu->RegisterInterruptHandler (mCpu, LOCAL_APIC_TIMER_VECTOR,
+ TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Force the timer to be enabled at its default period
+ //
+ Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the Timer Architectural Protocol onto a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mTimerHandle,
+ &gEfiTimerArchProtocolGuid, &mTimer,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 31/35] OvmfPkg/OvmfXen: Introduce XenTimerDxe
2019-07-04 14:42 ` [PATCH v3 31/35] OvmfPkg/OvmfXen: Introduce XenTimerDxe Anthony PERARD
@ 2019-07-10 10:12 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 10:12 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> "PcAtChipsetPkg/8254TimerDxe" is replaced with a Xen-specific
> EFI_TIMER_ARCH_PROTOCOL implementation. Also remove
> 8259InterruptControllerDxe as it is not used anymore.
>
> This Timer uses the local APIC timer as time source as it can work on
> both a Xen PVH guest and an HVM one.
>
> Based on the "PcAtChipsetPkg/8254TimerDxe" implementation.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - rebased, SPDX, copyright
(1) Please replace both occurrences of "PcAtChipsetPkg" in the commit
message with "OvmfPkg". (You rebased the DSC/FDF files correctly, but
missed the commit message.)
With that:
Acked-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (30 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 31/35] OvmfPkg/OvmfXen: Introduce XenTimerDxe Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 10:48 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
` (5 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
On a Xen PVH guest, none of the existing serial or console interface
works, so we add a new one, based on XenConsoleSerialPortLib, and
implemented via SerialDxe.
That is a simple console implementation that can works on both PVH
guest and HVM guests, even if it rarely going to be use on HVM.
Have PlatformBootManagerLib look for the new console, when running as a
Xen guest.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- removed PciSioSerialDxe and IsaSerialDxe from OvmfXen, since they
would not be used, maybe, to check.
- some coding style fix
- not changed: PciSioSerialDxe: even if we add SerialDxe, we still needs
PciSioSerialDxe to have OVMF use the emulated serial port on HVM.
v2:
- Use MdeModulePkg/Universal/SerialDxe instead of something new.
- Have PlatformInitializeConsole() look for it by using the
known-in-advance device path for the xen console in the
PLATFORM_CONSOLE_CONNECT_ENTRY.
OvmfPkg/OvmfXen.dsc | 4 ++
OvmfPkg/OvmfXen.fdf | 1 +
.../PlatformBootManagerLib.inf | 4 ++
.../PlatformBootManagerLib/BdsPlatform.h | 1 +
.../PlatformBootManagerLib/BdsPlatform.c | 3 +-
.../PlatformBootManagerLib/PlatformData.c | 59 ++++++++++++++++++-
6 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 1ecae3fb45..487bada64d 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -586,6 +586,10 @@ [Components]
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf {
+ <LibraryClasses>
+ SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
+ }
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index fa0830a324..5c1a925d6a 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -312,6 +312,7 @@ [FV.DXEFV]
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index b2d3b4fb4d..646a1c522c 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -61,6 +61,10 @@ [Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits ## CONSUMES
[Pcd.IA32, Pcd.X64]
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
index 49a072b400..153e215101 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -165,6 +165,7 @@ typedef struct {
#define CONSOLE_IN BIT1
#define STD_ERROR BIT2
extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
+extern PLATFORM_CONSOLE_CONNECT_ENTRY gXenPlatformConsole[];
//
// Platform BDS Functions
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 9ae590293a..ee6ee6608f 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -399,7 +399,8 @@ PlatformBootManagerBeforeConsole (
//
EfiBootManagerDispatchDeferredImages ();
- PlatformInitializeConsole (gPlatformConsole);
+ PlatformInitializeConsole (
+ XenDetected() ? gXenPlatformConsole : gPlatformConsole);
PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,
GetFrontPageTimeoutFromQemu ());
ASSERT_RETURN_ERROR (PcdStatus);
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
index 36aab784d7..a9b1fe274a 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -9,18 +9,19 @@
#include "BdsPlatform.h"
#include <Guid/QemuRamfb.h>
+#include <Guid/SerialPortLibVendor.h>
//
// Debug Agent UART Device Path structure
//
-#pragma pack(1)
+#pragma pack (1)
typedef struct {
VENDOR_DEVICE_PATH VendorHardware;
UART_DEVICE_PATH Uart;
VENDOR_DEVICE_PATH TerminalType;
EFI_DEVICE_PATH_PROTOCOL End;
} VENDOR_UART_DEVICE_PATH;
-#pragma pack()
+#pragma pack ()
//
// USB Keyboard Device Path structure
@@ -43,6 +44,18 @@ typedef struct {
} VENDOR_RAMFB_DEVICE_PATH;
#pragma pack ()
+//
+// Xen Console Device Path structure
+//
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorHardware;
+ UART_DEVICE_PATH Uart;
+ VENDOR_DEVICE_PATH TerminalType;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} XEN_CONSOLE_DEVICE_PATH;
+#pragma pack()
+
ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;
ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;
UART_DEVICE_PATH gUartDeviceNode = gUart;
@@ -141,6 +154,37 @@ STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {
gEndEntire
};
+STATIC XEN_CONSOLE_DEVICE_PATH gXenConsoleDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ EDKII_SERIAL_PORT_LIB_VENDOR_GUID
+ },
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ {
+ (UINT8) (sizeof (UART_DEVICE_PATH)),
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0,
+ FixedPcdGet64 (PcdUartDefaultBaudRate),
+ FixedPcdGet8 (PcdUartDefaultDataBits),
+ FixedPcdGet8 (PcdUartDefaultParity),
+ FixedPcdGet8 (PcdUartDefaultStopBits),
+ },
+ gPcAnsiTerminal,
+ gEndEntire
+};
+
//
// Predefined platform default console device path
//
@@ -163,6 +207,17 @@ PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
}
};
+PLATFORM_CONSOLE_CONNECT_ENTRY gXenPlatformConsole[] = {
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *)&gXenConsoleDevicePath,
+ (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+ },
+ {
+ NULL,
+ 0
+ }
+};
+
//
// Predefined platform connect sequence
//
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
2019-07-04 14:42 ` [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
@ 2019-07-10 10:48 ` Laszlo Ersek
2019-07-22 17:06 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 10:48 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> On a Xen PVH guest, none of the existing serial or console interface
> works, so we add a new one, based on XenConsoleSerialPortLib, and
> implemented via SerialDxe.
>
> That is a simple console implementation that can works on both PVH
> guest and HVM guests, even if it rarely going to be use on HVM.
>
> Have PlatformBootManagerLib look for the new console, when running as a
> Xen guest.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - removed PciSioSerialDxe and IsaSerialDxe from OvmfXen, since they
> would not be used, maybe, to check.
> - some coding style fix
>
> - not changed: PciSioSerialDxe: even if we add SerialDxe, we still needs
> PciSioSerialDxe to have OVMF use the emulated serial port on HVM.
>
> v2:
> - Use MdeModulePkg/Universal/SerialDxe instead of something new.
> - Have PlatformInitializeConsole() look for it by using the
> known-in-advance device path for the xen console in the
> PLATFORM_CONSOLE_CONNECT_ENTRY.
>
> OvmfPkg/OvmfXen.dsc | 4 ++
> OvmfPkg/OvmfXen.fdf | 1 +
> .../PlatformBootManagerLib.inf | 4 ++
> .../PlatformBootManagerLib/BdsPlatform.h | 1 +
> .../PlatformBootManagerLib/BdsPlatform.c | 3 +-
> .../PlatformBootManagerLib/PlatformData.c | 59 ++++++++++++++++++-
> 6 files changed, 69 insertions(+), 3 deletions(-)
>
> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> index 1ecae3fb45..487bada64d 100644
> --- a/OvmfPkg/OvmfXen.dsc
> +++ b/OvmfPkg/OvmfXen.dsc
> @@ -586,6 +586,10 @@ [Components]
> OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> OvmfPkg/XenBusDxe/XenBusDxe.inf
> OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf {
> + <LibraryClasses>
> + SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> + }
> MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
> index fa0830a324..5c1a925d6a 100644
> --- a/OvmfPkg/OvmfXen.fdf
> +++ b/OvmfPkg/OvmfXen.fdf
> @@ -312,6 +312,7 @@ [FV.DXEFV]
> INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> INF OvmfPkg/XenBusDxe/XenBusDxe.inf
> INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> +INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
>
> INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index b2d3b4fb4d..646a1c522c 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -61,6 +61,10 @@ [Pcd]
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## CONSUMES
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits ## CONSUMES
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity ## CONSUMES
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits ## CONSUMES
>
> [Pcd.IA32, Pcd.X64]
> gEfiMdePkgTokenSpaceGuid.PcdFSBClock
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
> index 49a072b400..153e215101 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
> @@ -165,6 +165,7 @@ typedef struct {
> #define CONSOLE_IN BIT1
> #define STD_ERROR BIT2
> extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
> +extern PLATFORM_CONSOLE_CONNECT_ENTRY gXenPlatformConsole[];
>
> //
> // Platform BDS Functions
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index 9ae590293a..ee6ee6608f 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -399,7 +399,8 @@ PlatformBootManagerBeforeConsole (
> //
> EfiBootManagerDispatchDeferredImages ();
>
> - PlatformInitializeConsole (gPlatformConsole);
> + PlatformInitializeConsole (
> + XenDetected() ? gXenPlatformConsole : gPlatformConsole);
> PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,
> GetFrontPageTimeoutFromQemu ());
> ASSERT_RETURN_ERROR (PcdStatus);
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> index 36aab784d7..a9b1fe274a 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> @@ -9,18 +9,19 @@
>
> #include "BdsPlatform.h"
> #include <Guid/QemuRamfb.h>
> +#include <Guid/SerialPortLibVendor.h>
>
> //
> // Debug Agent UART Device Path structure
> //
> -#pragma pack(1)
> +#pragma pack (1)
> typedef struct {
> VENDOR_DEVICE_PATH VendorHardware;
> UART_DEVICE_PATH Uart;
> VENDOR_DEVICE_PATH TerminalType;
> EFI_DEVICE_PATH_PROTOCOL End;
> } VENDOR_UART_DEVICE_PATH;
> -#pragma pack()
> +#pragma pack ()
>
> //
> // USB Keyboard Device Path structure
> @@ -43,6 +44,18 @@ typedef struct {
> } VENDOR_RAMFB_DEVICE_PATH;
> #pragma pack ()
>
> +//
> +// Xen Console Device Path structure
> +//
> +#pragma pack(1)
> +typedef struct {
> + VENDOR_DEVICE_PATH VendorHardware;
> + UART_DEVICE_PATH Uart;
> + VENDOR_DEVICE_PATH TerminalType;
> + EFI_DEVICE_PATH_PROTOCOL End;
> +} XEN_CONSOLE_DEVICE_PATH;
> +#pragma pack()
> +
This version of the patch addresses all of my v2 review comments (either
by code changes or by explanations in the Notes section) -- thanks for that.
However, when you arrived at my reuqest (6) in
<http://mid.mail-archive.com/7d6adf5d-baca-7e9c-68ef-2f8479bbd902@redhat.com>,
and searched the source file for "pack(" -- in order to insert a space
character before the opening paren --, the match was *not* around the
new XEN_CONSOLE_DEVICE_PATH structure. Instead, it was around the
preexistent VENDOR_UART_DEVICE_PATH structure. And so you fixed the
style for the old code, and not the new code.
But: that's actually useful. Because now that I'm looking at
VENDOR_UART_DEVICE_PATH, it seems that we don't need the new type
XEN_CONSOLE_DEVICE_PATH at all. Is that right? So:
(1) Please drop XEN_CONSOLE_DEVICE_PATH.
(2) Please replace the comment
Debug Agent UART Device Path structure
with
Vendor UART Device Path structure
on VENDOR_UART_DEVICE_PATH.
(3) Please preserve the "misplaced" whitespace fix, for "pack(", around
VENDOR_UART_DEVICE_PATH.
(4) Please use VENDOR_UART_DEVICE_PATH as the type of gXenConsoleDevicePath.
With those:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks!
Laszlo
> ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;
> ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;
> UART_DEVICE_PATH gUartDeviceNode = gUart;
> @@ -141,6 +154,37 @@ STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {
> gEndEntire
> };
>
> +STATIC XEN_CONSOLE_DEVICE_PATH gXenConsoleDevicePath = {
> + {
> + {
> + HARDWARE_DEVICE_PATH,
> + HW_VENDOR_DP,
> + {
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> + }
> + },
> + EDKII_SERIAL_PORT_LIB_VENDOR_GUID
> + },
> + {
> + {
> + MESSAGING_DEVICE_PATH,
> + MSG_UART_DP,
> + {
> + (UINT8) (sizeof (UART_DEVICE_PATH)),
> + (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)
> + }
> + },
> + 0,
> + FixedPcdGet64 (PcdUartDefaultBaudRate),
> + FixedPcdGet8 (PcdUartDefaultDataBits),
> + FixedPcdGet8 (PcdUartDefaultParity),
> + FixedPcdGet8 (PcdUartDefaultStopBits),
> + },
> + gPcAnsiTerminal,
> + gEndEntire
> +};
> +
> //
> // Predefined platform default console device path
> //
> @@ -163,6 +207,17 @@ PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
> }
> };
>
> +PLATFORM_CONSOLE_CONNECT_ENTRY gXenPlatformConsole[] = {
> + {
> + (EFI_DEVICE_PATH_PROTOCOL *)&gXenConsoleDevicePath,
> + (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
> + },
> + {
> + NULL,
> + 0
> + }
> +};
> +
> //
> // Predefined platform connect sequence
> //
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
2019-07-10 10:48 ` Laszlo Ersek
@ 2019-07-22 17:06 ` Anthony PERARD
2019-07-23 7:31 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-22 17:06 UTC (permalink / raw)
To: Laszlo Ersek
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On Wed, Jul 10, 2019 at 12:48:57PM +0200, Laszlo Ersek wrote:
> On 07/04/19 16:42, Anthony PERARD wrote:
> > On a Xen PVH guest, none of the existing serial or console interface
> > works, so we add a new one, based on XenConsoleSerialPortLib, and
> > implemented via SerialDxe.
> >
> > That is a simple console implementation that can works on both PVH
> > guest and HVM guests, even if it rarely going to be use on HVM.
> >
> > Have PlatformBootManagerLib look for the new console, when running as a
> > Xen guest.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> > ---
> > diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> > index 36aab784d7..a9b1fe274a 100644
> > --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> > +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> > @@ -9,18 +9,19 @@
> >
> > #include "BdsPlatform.h"
> > #include <Guid/QemuRamfb.h>
> > +#include <Guid/SerialPortLibVendor.h>
> >
> > //
> > // Debug Agent UART Device Path structure
> > //
> > -#pragma pack(1)
> > +#pragma pack (1)
> > typedef struct {
> > VENDOR_DEVICE_PATH VendorHardware;
> > UART_DEVICE_PATH Uart;
> > VENDOR_DEVICE_PATH TerminalType;
> > EFI_DEVICE_PATH_PROTOCOL End;
> > } VENDOR_UART_DEVICE_PATH;
> > -#pragma pack()
> > +#pragma pack ()
> >
> > //
> > // USB Keyboard Device Path structure
> > @@ -43,6 +44,18 @@ typedef struct {
> > } VENDOR_RAMFB_DEVICE_PATH;
> > #pragma pack ()
> >
> > +//
> > +// Xen Console Device Path structure
> > +//
> > +#pragma pack(1)
> > +typedef struct {
> > + VENDOR_DEVICE_PATH VendorHardware;
> > + UART_DEVICE_PATH Uart;
> > + VENDOR_DEVICE_PATH TerminalType;
> > + EFI_DEVICE_PATH_PROTOCOL End;
> > +} XEN_CONSOLE_DEVICE_PATH;
> > +#pragma pack()
> > +
>
> This version of the patch addresses all of my v2 review comments (either
> by code changes or by explanations in the Notes section) -- thanks for that.
>
> However, when you arrived at my reuqest (6) in
> <http://mid.mail-archive.com/7d6adf5d-baca-7e9c-68ef-2f8479bbd902@redhat.com>,
> and searched the source file for "pack(" -- in order to insert a space
> character before the opening paren --, the match was *not* around the
> new XEN_CONSOLE_DEVICE_PATH structure. Instead, it was around the
> preexistent VENDOR_UART_DEVICE_PATH structure. And so you fixed the
> style for the old code, and not the new code.
>
> But: that's actually useful. Because now that I'm looking at
> VENDOR_UART_DEVICE_PATH, it seems that we don't need the new type
> XEN_CONSOLE_DEVICE_PATH at all. Is that right? So:
>
> (1) Please drop XEN_CONSOLE_DEVICE_PATH.
>
> (2) Please replace the comment
>
> Debug Agent UART Device Path structure
>
> with
>
> Vendor UART Device Path structure
>
> on VENDOR_UART_DEVICE_PATH.
>
> (3) Please preserve the "misplaced" whitespace fix, for "pack(", around
> VENDOR_UART_DEVICE_PATH.
>
> (4) Please use VENDOR_UART_DEVICE_PATH as the type of gXenConsoleDevicePath.
>
> With those:
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
I'm going to add the following to the commit message:
Since we use VENDOR_UART_DEVICE_PATH, fix its description and
coding style.
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
2019-07-22 17:06 ` Anthony PERARD
@ 2019-07-23 7:31 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-23 7:31 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/22/19 19:06, Anthony PERARD wrote:
> On Wed, Jul 10, 2019 at 12:48:57PM +0200, Laszlo Ersek wrote:
>> On 07/04/19 16:42, Anthony PERARD wrote:
>>> On a Xen PVH guest, none of the existing serial or console interface
>>> works, so we add a new one, based on XenConsoleSerialPortLib, and
>>> implemented via SerialDxe.
>>>
>>> That is a simple console implementation that can works on both PVH
>>> guest and HVM guests, even if it rarely going to be use on HVM.
>>>
>>> Have PlatformBootManagerLib look for the new console, when running as a
>>> Xen guest.
>>>
>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
>>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>>> ---
>
>>> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
>>> index 36aab784d7..a9b1fe274a 100644
>>> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
>>> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
>>> @@ -9,18 +9,19 @@
>>>
>>> #include "BdsPlatform.h"
>>> #include <Guid/QemuRamfb.h>
>>> +#include <Guid/SerialPortLibVendor.h>
>>>
>>> //
>>> // Debug Agent UART Device Path structure
>>> //
>>> -#pragma pack(1)
>>> +#pragma pack (1)
>>> typedef struct {
>>> VENDOR_DEVICE_PATH VendorHardware;
>>> UART_DEVICE_PATH Uart;
>>> VENDOR_DEVICE_PATH TerminalType;
>>> EFI_DEVICE_PATH_PROTOCOL End;
>>> } VENDOR_UART_DEVICE_PATH;
>>> -#pragma pack()
>>> +#pragma pack ()
>>>
>>> //
>>> // USB Keyboard Device Path structure
>>> @@ -43,6 +44,18 @@ typedef struct {
>>> } VENDOR_RAMFB_DEVICE_PATH;
>>> #pragma pack ()
>>>
>>> +//
>>> +// Xen Console Device Path structure
>>> +//
>>> +#pragma pack(1)
>>> +typedef struct {
>>> + VENDOR_DEVICE_PATH VendorHardware;
>>> + UART_DEVICE_PATH Uart;
>>> + VENDOR_DEVICE_PATH TerminalType;
>>> + EFI_DEVICE_PATH_PROTOCOL End;
>>> +} XEN_CONSOLE_DEVICE_PATH;
>>> +#pragma pack()
>>> +
>>
>> This version of the patch addresses all of my v2 review comments (either
>> by code changes or by explanations in the Notes section) -- thanks for that.
>>
>> However, when you arrived at my reuqest (6) in
>> <http://mid.mail-archive.com/7d6adf5d-baca-7e9c-68ef-2f8479bbd902@redhat.com>,
>> and searched the source file for "pack(" -- in order to insert a space
>> character before the opening paren --, the match was *not* around the
>> new XEN_CONSOLE_DEVICE_PATH structure. Instead, it was around the
>> preexistent VENDOR_UART_DEVICE_PATH structure. And so you fixed the
>> style for the old code, and not the new code.
>>
>> But: that's actually useful. Because now that I'm looking at
>> VENDOR_UART_DEVICE_PATH, it seems that we don't need the new type
>> XEN_CONSOLE_DEVICE_PATH at all. Is that right? So:
>>
>> (1) Please drop XEN_CONSOLE_DEVICE_PATH.
>>
>> (2) Please replace the comment
>>
>> Debug Agent UART Device Path structure
>>
>> with
>>
>> Vendor UART Device Path structure
>>
>> on VENDOR_UART_DEVICE_PATH.
>>
>> (3) Please preserve the "misplaced" whitespace fix, for "pack(", around
>> VENDOR_UART_DEVICE_PATH.
>>
>> (4) Please use VENDOR_UART_DEVICE_PATH as the type of gXenConsoleDevicePath.
>>
>> With those:
>>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>
> I'm going to add the following to the commit message:
>
> Since we use VENDOR_UART_DEVICE_PATH, fix its description and
> coding style.
>
>
Thanks!
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (31 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 32/35] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-10 14:05 ` Laszlo Ersek
2019-07-04 14:42 ` [PATCH v3 34/35] OvmfPkg: Move XenRealTimeClockLib from ArmVirtPkg Anthony PERARD
` (4 subsequent siblings)
37 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
XenIoPvhDxe use XenIoMmioLib to reserve some space to be use by the
Grant Tables.
The call is only done if it is necessary, we simply detect if the
guest is PVH, as in this case there is currently no PCI bus, and no
PCI Xen platform device which would start the XenIoPciDxe and allocate
the space for the Grant Tables.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
Notes:
v3:
- downgrade type to DXE_DRIVER
- use SPDX
- rework InitializeXenIoPvhDxe, and handle errors properly.
- Free the reserved allocation in ExitBootServices even if the XenIo
protocol could successfully been uninstalled.
v2:
- do allocation in EntryPoint like the other user of XenIoMmioLib.
- allocate memory instead of hardcoded addr.
- cleanup, add copyright
- detect if we are running in PVH mode
OvmfPkg/OvmfXen.dsc | 2 +
OvmfPkg/OvmfXen.fdf | 1 +
OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf | 34 +++++++++
OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c | 108 ++++++++++++++++++++++++++++
4 files changed, 145 insertions(+)
create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 487bada64d..af92ce3ed2 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -196,6 +196,7 @@ [LibraryClasses]
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
+ XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
@@ -583,6 +584,7 @@ [Components]
NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
!endif
}
+ OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
OvmfPkg/XenBusDxe/XenBusDxe.inf
OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 5c1a925d6a..517a492f14 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -309,6 +309,7 @@ [FV.DXEFV]
INF MdeModulePkg/Universal/Metronome/Metronome.inf
INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
INF OvmfPkg/XenBusDxe/XenBusDxe.inf
INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
new file mode 100644
index 0000000000..a093d48fde
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
@@ -0,0 +1,34 @@
+## @file
+# Driver for the XenIo protocol
+#
+# Copyright (c) 2019, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = XenIoPvhDxe
+ FILE_GUID = 7a567cc4-0e75-4d7a-a305-c3db109b53ad
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeXenIoPvhDxe
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Sources]
+ XenIoPvhDxe.c
+
+[LibraryClasses]
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ XenIoMmioLib
+ XenPlatformLib
+
+[Depex]
+ TRUE
diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
new file mode 100644
index 0000000000..88a394bf91
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
@@ -0,0 +1,108 @@
+/** @file
+
+ Driver for the XenIo protocol
+
+ This driver simply allocate space for the grant tables.
+
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/XenIoMmioLib.h>
+#include <Library/XenPlatformLib.h>
+
+typedef struct {
+ EFI_HANDLE XenIoHandle;
+ EFI_EVENT ExitBootEvent;
+ VOID *Allocation;
+} XEN_IO_PVH_STATE;
+
+//
+// Value should be the same as NR_GRANT_FRAMES in XenBusDxe
+//
+#define XEN_GRANT_FRAMES 4
+
+STATIC
+VOID
+EFIAPI
+XenIoPvhDxeNotifyExitBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ XEN_IO_PVH_STATE *State;
+ EFI_STATUS Status;
+
+ State = Context;
+
+ gBS->CloseEvent(&State->ExitBootEvent);
+ Status = XenIoMmioUninstall(State->XenIoHandle);
+ if (Status == EFI_SUCCESS) {
+ //
+ // Only free the reserved space for grant table if no driver is using it.
+ //
+ FreePages (State->Allocation, XEN_GRANT_FRAMES);
+ }
+ FreePool (State);
+}
+
+EFI_STATUS
+EFIAPI
+InitializeXenIoPvhDxe (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VOID *Allocation;
+ EFI_STATUS Status;
+ XEN_IO_PVH_STATE *State;
+
+ State = NULL;
+ Allocation = NULL;
+
+ if (! XenPvhDetected ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ State = AllocatePool (sizeof (*State));
+ if (State == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Allocation = AllocateReservedPages (XEN_GRANT_FRAMES);
+ if (Allocation == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ State->XenIoHandle = NULL;
+ Status = XenIoMmioInstall (&State->XenIoHandle, (UINTN) Allocation);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ State->Allocation = Allocation;
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
+ XenIoPvhDxeNotifyExitBoot, State, &State->ExitBootEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+
+Error:
+ if (State != NULL && State->XenIoHandle != NULL) {
+ XenIoMmioUninstall(State->XenIoHandle);
+ }
+ if (Allocation != NULL) {
+ FreePages (Allocation, XEN_GRANT_FRAMES);
+ }
+ if (State != NULL) {
+ FreePool (State);
+ }
+ return Status;
+}
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
2019-07-04 14:42 ` [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
@ 2019-07-10 14:05 ` Laszlo Ersek
2019-07-26 16:06 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 14:05 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/04/19 16:42, Anthony PERARD wrote:
> XenIoPvhDxe use XenIoMmioLib to reserve some space to be use by the
> Grant Tables.
>
> The call is only done if it is necessary, we simply detect if the
> guest is PVH, as in this case there is currently no PCI bus, and no
> PCI Xen platform device which would start the XenIoPciDxe and allocate
> the space for the Grant Tables.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>
> Notes:
> v3:
> - downgrade type to DXE_DRIVER
> - use SPDX
> - rework InitializeXenIoPvhDxe, and handle errors properly.
> - Free the reserved allocation in ExitBootServices even if the XenIo
> protocol could successfully been uninstalled.
>
> v2:
> - do allocation in EntryPoint like the other user of XenIoMmioLib.
> - allocate memory instead of hardcoded addr.
> - cleanup, add copyright
> - detect if we are running in PVH mode
>
> OvmfPkg/OvmfXen.dsc | 2 +
> OvmfPkg/OvmfXen.fdf | 1 +
> OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf | 34 +++++++++
> OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c | 108 ++++++++++++++++++++++++++++
> 4 files changed, 145 insertions(+)
> create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
>
> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> index 487bada64d..af92ce3ed2 100644
> --- a/OvmfPkg/OvmfXen.dsc
> +++ b/OvmfPkg/OvmfXen.dsc
> @@ -196,6 +196,7 @@ [LibraryClasses]
> OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
> + XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
>
> Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
>
> @@ -583,6 +584,7 @@ [Components]
> NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
> !endif
> }
> + OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> OvmfPkg/XenBusDxe/XenBusDxe.inf
> OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
> index 5c1a925d6a..517a492f14 100644
> --- a/OvmfPkg/OvmfXen.fdf
> +++ b/OvmfPkg/OvmfXen.fdf
> @@ -309,6 +309,7 @@ [FV.DXEFV]
> INF MdeModulePkg/Universal/Metronome/Metronome.inf
> INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
>
> +INF OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> INF OvmfPkg/XenBusDxe/XenBusDxe.inf
> INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> new file mode 100644
> index 0000000000..a093d48fde
> --- /dev/null
> +++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> @@ -0,0 +1,34 @@
> +## @file
> +# Driver for the XenIo protocol
> +#
> +# Copyright (c) 2019, Citrix Systems, Inc.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = XenIoPvhDxe
> + FILE_GUID = 7a567cc4-0e75-4d7a-a305-c3db109b53ad
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = InitializeXenIoPvhDxe
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[Sources]
> + XenIoPvhDxe.c
> +
> +[LibraryClasses]
> + DebugLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> + XenIoMmioLib
> + XenPlatformLib
> +
> +[Depex]
> + TRUE
> diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
> new file mode 100644
> index 0000000000..88a394bf91
> --- /dev/null
> +++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
> @@ -0,0 +1,108 @@
> +/** @file
> +
> + Driver for the XenIo protocol
> +
> + This driver simply allocate space for the grant tables.
> +
> + Copyright (c) 2019, Citrix Systems, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/XenIoMmioLib.h>
> +#include <Library/XenPlatformLib.h>
> +
> +typedef struct {
> + EFI_HANDLE XenIoHandle;
> + EFI_EVENT ExitBootEvent;
> + VOID *Allocation;
> +} XEN_IO_PVH_STATE;
> +
> +//
> +// Value should be the same as NR_GRANT_FRAMES in XenBusDxe
> +//
> +#define XEN_GRANT_FRAMES 4
In v2, this was a "naked" integer constant, and I didn't realize it was
supposed to match XenBusDxe.
(1) Please insert a separate patch before this patch, that turns the
value 4 in XenBusDxe into a FixedAtBuild PCD, in "OvmfPkg.dec":
[PcdsFixedAtBuild]
## Number of page frames to use for storing grant table entries.
# Must be less than or equal to what is configured in the Xen HV.
gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
In "XenBusDxe.inf", introduce a [FixedPcd] section, for expressing the
dependency on the PCD.
And in the code, use
FixedPcdGet32 (PcdXenGrantFrames)
This will expand to an integer constant, and so it is suitable for use
in further #define's.
> +
> +STATIC
> +VOID
> +EFIAPI
> +XenIoPvhDxeNotifyExitBoot (
> + IN EFI_EVENT Event,
> + IN VOID *Context
> + )
> +{
> + XEN_IO_PVH_STATE *State;
> + EFI_STATUS Status;
> +
> + State = Context;
> +
> + gBS->CloseEvent(&State->ExitBootEvent);
> + Status = XenIoMmioUninstall(State->XenIoHandle);
> + if (Status == EFI_SUCCESS) {
> + //
> + // Only free the reserved space for grant table if no driver is using it.
> + //
> + FreePages (State->Allocation, XEN_GRANT_FRAMES);
> + }
> + FreePool (State);
> +}
In my v2 review at
http://mid.mail-archive.com/2c386393-b886-a7e7-e8b9-c5e339c94727@redhat.com
I asked, in point (6), whether we needed the memory allocation to be
"reserved". I guess this change (in v3) is supposed to address that.
(And, indeed, version 3 of this patch correctly addresses all other
points from my v2 review.)
However: an ExitBootServices notification function *must not* perform
actions that could change the UEFI memory map. Thus, you can not release
memory there -- you can't call CloseEvent(),
UninstallMultipleProtocolInterfaces(), FreePool(), FreePages(), and so on.
In my earlier review, I wrote,
> [...] then we could allocate EfiBootServicesData type memory here --
> and perhaps add an ExitBootServices() callback to disconnect from Xen
> [...]
By "disconnect", I meant actions that do *not* include memory allocation
/ release, but only make the hypervisor *forget* its guest RAM
references that it currently holds.
ExitBootServices() handlers (notification functions) are different from
normal "teardown" functions. A "teardown" function generally mirrors a
"construct" function, where you remove all references, and release all
memory allocations, in precise reverse order of construction.
ExitBootServices() handlers perform a *subsequence* of that (usually
preserving the same relative order between the steps): you only erase
external references to RAM -- that is, RAM references that are held by
external entities, such as PCI devices (in-flight DMA), the hypervisor,
and so on. The referred-to RAM, originally allocated as "boot services
data", will be released later, whole-sale, by the OS.
In that sense, ExitBootServices() callbacks implement a kind of
ownership transfer. You no longer own the UEFI memory map, you just have
to kick out such external references into it that the OS would not know
about.
To summarize:
- If this memory *needs* to be reserved past ExitBootServices(), then
stick with AllocateReservedPages(). Otherwise, use AllocatePages(); then
the pages will be freed automatically by the OS, soon after it is started.
- In the latter case, if necessary, you can make the hypervisor forget
about the area, as part of ExitBootServices(), in a notification
function. But that can only happen without allocating or releasing
memory in the notification function.
... I guess you could make a XENMEM_remove_from_physmap hypercall, for
example. But, it's *entirely* possible that said hypercall doesn't
belong in *this* driver. After all, this is not the driver that calls
XENMEM_add_to_physmap either!
... In fact, I think XenBusDxe has a bug. Right now, you have the
following call chain, when the OS calls ExitBootServices():
NotifyExitBoot()
gBS->DisconnectController()
XenBusDxeDriverBindingStop()
XenGrantTableDeinit()
XenHypercallMemoryOp (XENMEM_remove_from_physmap)
Unfortunately, this call tree releases memory left and right, and so it
is not valid on the stack of gBS->ExitBootServices().
Instead, NotifyExitBoot() should collect just the subsequence of
XenBusDxeDriverBindingStop() -- interpreting that function as a flatened
sequence of operations -- that removes external references to RAM.
Making hypercalls (using parameters constructed on the stack) is fine.
Using dynamically *pre*allocated memory (for constructing hypercall
arguments) is also fine. Dynamically allocating or releasing memory *on
the spot* is not fine.
(2) So, for now, I'd recommend simply removing
XenIoPvhDxeNotifyExitBoot(), in this patch.
You might want to fix XenBusDxe's NotifyExitBoot(), separately.
> +
> +EFI_STATUS
> +EFIAPI
> +InitializeXenIoPvhDxe (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + VOID *Allocation;
> + EFI_STATUS Status;
> + XEN_IO_PVH_STATE *State;
> +
> + State = NULL;
> + Allocation = NULL;
> +
> + if (! XenPvhDetected ()) {
(3) Please drop the space character. It's not invalid, but quite foreign
in edk2, I'd say.
> + return EFI_UNSUPPORTED;
> + }
> +
> + State = AllocatePool (sizeof (*State));
(4) What do we gain by allocating "State" dynamically? IMO, it could be
a local variable (= "automatic storage duration").
> + if (State == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + Allocation = AllocateReservedPages (XEN_GRANT_FRAMES);
(5) So, again, please evaluate if this could simply be AllocatePages().
Thanks
Laszlo
> + if (Allocation == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + State->XenIoHandle = NULL;
> + Status = XenIoMmioInstall (&State->XenIoHandle, (UINTN) Allocation);
> + if (EFI_ERROR (Status)) {
> + goto Error;
> + }
> +
> + State->Allocation = Allocation;
> + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
> + XenIoPvhDxeNotifyExitBoot, State, &State->ExitBootEvent);
> + ASSERT_EFI_ERROR (Status);
> +
> + return EFI_SUCCESS;
> +
> +Error:
> + if (State != NULL && State->XenIoHandle != NULL) {
> + XenIoMmioUninstall(State->XenIoHandle);
> + }
> + if (Allocation != NULL) {
> + FreePages (Allocation, XEN_GRANT_FRAMES);
> + }
> + if (State != NULL) {
> + FreePool (State);
> + }
> + return Status;
> +}
>
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
2019-07-10 14:05 ` Laszlo Ersek
@ 2019-07-26 16:06 ` Anthony PERARD
2019-07-26 17:19 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-26 16:06 UTC (permalink / raw)
To: Laszlo Ersek
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On Wed, Jul 10, 2019 at 04:05:02PM +0200, Laszlo Ersek wrote:
> On 07/04/19 16:42, Anthony PERARD wrote:
> > +
> > +STATIC
> > +VOID
> > +EFIAPI
> > +XenIoPvhDxeNotifyExitBoot (
> > + IN EFI_EVENT Event,
> > + IN VOID *Context
> > + )
> > +{
> > + XEN_IO_PVH_STATE *State;
> > + EFI_STATUS Status;
> > +
> > + State = Context;
> > +
> > + gBS->CloseEvent(&State->ExitBootEvent);
> > + Status = XenIoMmioUninstall(State->XenIoHandle);
> > + if (Status == EFI_SUCCESS) {
> > + //
> > + // Only free the reserved space for grant table if no driver is using it.
> > + //
> > + FreePages (State->Allocation, XEN_GRANT_FRAMES);
> > + }
> > + FreePool (State);
> > +}
>
> In my v2 review at
>
> http://mid.mail-archive.com/2c386393-b886-a7e7-e8b9-c5e339c94727@redhat.com
>
> I asked, in point (6), whether we needed the memory allocation to be
> "reserved". I guess this change (in v3) is supposed to address that.
> (And, indeed, version 3 of this patch correctly addresses all other
> points from my v2 review.)
>
> However: an ExitBootServices notification function *must not* perform
> actions that could change the UEFI memory map. Thus, you can not release
> memory there -- you can't call CloseEvent(),
> UninstallMultipleProtocolInterfaces(), FreePool(), FreePages(), and so on.
>
> In my earlier review, I wrote,
>
> > [...] then we could allocate EfiBootServicesData type memory here --
> > and perhaps add an ExitBootServices() callback to disconnect from Xen
> > [...]
>
> By "disconnect", I meant actions that do *not* include memory allocation
> / release, but only make the hypervisor *forget* its guest RAM
> references that it currently holds.
>
> ExitBootServices() handlers (notification functions) are different from
> normal "teardown" functions. A "teardown" function generally mirrors a
> "construct" function, where you remove all references, and release all
> memory allocations, in precise reverse order of construction.
>
> ExitBootServices() handlers perform a *subsequence* of that (usually
> preserving the same relative order between the steps): you only erase
> external references to RAM -- that is, RAM references that are held by
> external entities, such as PCI devices (in-flight DMA), the hypervisor,
> and so on. The referred-to RAM, originally allocated as "boot services
> data", will be released later, whole-sale, by the OS.
>
> In that sense, ExitBootServices() callbacks implement a kind of
> ownership transfer. You no longer own the UEFI memory map, you just have
> to kick out such external references into it that the OS would not know
> about.
>
> To summarize:
>
> - If this memory *needs* to be reserved past ExitBootServices(), then
> stick with AllocateReservedPages(). Otherwise, use AllocatePages(); then
> the pages will be freed automatically by the OS, soon after it is started.
>
> - In the latter case, if necessary, you can make the hypervisor forget
> about the area, as part of ExitBootServices(), in a notification
> function. But that can only happen without allocating or releasing
> memory in the notification function.
>
>
> ... I guess you could make a XENMEM_remove_from_physmap hypercall, for
> example. But, it's *entirely* possible that said hypercall doesn't
> belong in *this* driver. After all, this is not the driver that calls
> XENMEM_add_to_physmap either!
>
> ... In fact, I think XenBusDxe has a bug. Right now, you have the
> following call chain, when the OS calls ExitBootServices():
>
> NotifyExitBoot()
> gBS->DisconnectController()
> XenBusDxeDriverBindingStop()
> XenGrantTableDeinit()
> XenHypercallMemoryOp (XENMEM_remove_from_physmap)
>
> Unfortunately, this call tree releases memory left and right, and so it
> is not valid on the stack of gBS->ExitBootServices().
>
> Instead, NotifyExitBoot() should collect just the subsequence of
> XenBusDxeDriverBindingStop() -- interpreting that function as a flatened
> sequence of operations -- that removes external references to RAM.
> Making hypercalls (using parameters constructed on the stack) is fine.
> Using dynamically *pre*allocated memory (for constructing hypercall
> arguments) is also fine. Dynamically allocating or releasing memory *on
> the spot* is not fine.
>
> (2) So, for now, I'd recommend simply removing
> XenIoPvhDxeNotifyExitBoot(), in this patch.
Ok, I'll remove it.
> You might want to fix XenBusDxe's NotifyExitBoot(), separately.
I'll put that on my TODO list.
> > + return EFI_UNSUPPORTED;
> > + }
> > +
> > + State = AllocatePool (sizeof (*State));
>
> (4) What do we gain by allocating "State" dynamically? IMO, it could be
> a local variable (= "automatic storage duration").
Without the exit boot notification, State isn't needed anymore, so I'll
remove it.
> > + if (State == NULL) {
> > + Status = EFI_OUT_OF_RESOURCES;
> > + goto Error;
> > + }
> > +
> > + Allocation = AllocateReservedPages (XEN_GRANT_FRAMES);
>
> (5) So, again, please evaluate if this could simply be AllocatePages().
I would prefer to let know the operating system that those pages are
potentially used, unless I'm sure OVMF has let know Xen that those
pages don't contain the grant table anymore.
I'll probably try to make some changes in OVMF to allow to give back
those pages, but for now I think keeping those pages as reserved will
be good enough.
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
2019-07-26 16:06 ` Anthony PERARD
@ 2019-07-26 17:19 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-26 17:19 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall
On 07/26/19 18:06, Anthony PERARD wrote:
> On Wed, Jul 10, 2019 at 04:05:02PM +0200, Laszlo Ersek wrote:
>> On 07/04/19 16:42, Anthony PERARD wrote:
>>> + if (State == NULL) {
>>> + Status = EFI_OUT_OF_RESOURCES;
>>> + goto Error;
>>> + }
>>> +
>>> + Allocation = AllocateReservedPages (XEN_GRANT_FRAMES);
>>
>> (5) So, again, please evaluate if this could simply be AllocatePages().
>
> I would prefer to let know the operating system that those pages are
> potentially used, unless I'm sure OVMF has let know Xen that those
> pages don't contain the grant table anymore.
>
> I'll probably try to make some changes in OVMF to allow to give back
> those pages, but for now I think keeping those pages as reserved will
> be good enough.
Fair enough!
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* [PATCH v3 34/35] OvmfPkg: Move XenRealTimeClockLib from ArmVirtPkg
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (32 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 33/35] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-04 14:42 ` [PATCH v3 35/35] OvmfPkg/OvmfXen: use RealTimeClockRuntimeDxe from EmbeddedPkg Anthony PERARD
` (3 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
Move XenRealTimeClockLib from ArmVirtPkg to OvmfPkg so it can be used
from the OvmfPkg by the following patch, "OvmfPkg/OvmfXen: use
RealTimeClockRuntimeDxe from EmbeddedPkg"
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- fix the commit message body
ArmVirtPkg/ArmVirtXen.dsc | 2 +-
.../Library/XenRealTimeClockLib/XenRealTimeClockLib.inf | 0
.../Library/XenRealTimeClockLib/XenRealTimeClockLib.c | 0
3 files changed, 1 insertion(+), 1 deletion(-)
rename {ArmVirtPkg => OvmfPkg}/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf (100%)
rename {ArmVirtPkg => OvmfPkg}/Library/XenRealTimeClockLib/XenRealTimeClockLib.c (100%)
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 79304ee61d..1b42a9a813 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -27,7 +27,7 @@ [Defines]
[LibraryClasses]
SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
- RealTimeClockLib|ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
+ RealTimeClockLib|OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
ArmGenericTimerCounterLib|ArmVirtPkg/Library/XenArmGenericTimerVirtCounterLib/XenArmGenericTimerVirtCounterLib.inf
diff --git a/ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
similarity index 100%
rename from ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
rename to OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
diff --git a/ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c b/OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
similarity index 100%
rename from ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
rename to OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.c
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* [PATCH v3 35/35] OvmfPkg/OvmfXen: use RealTimeClockRuntimeDxe from EmbeddedPkg
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (33 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 34/35] OvmfPkg: Move XenRealTimeClockLib from ArmVirtPkg Anthony PERARD
@ 2019-07-04 14:42 ` Anthony PERARD
2019-07-05 12:21 ` [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
` (2 subsequent siblings)
37 siblings, 0 replies; 90+ messages in thread
From: Anthony PERARD @ 2019-07-04 14:42 UTC (permalink / raw)
To: devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Laszlo Ersek,
Julien Grall, Anthony PERARD
A Xen PVH guest doesn't have a RTC that OVMF would expect, so
PcatRealTimeClockRuntimeDxe fails to initialize and prevent the
firmware from finish to boot. To prevent that, we will use
XenRealTimeClockLib which simply always return the same time.
This will work on both Xen PVH and HVM guests.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
v3:
- moved RealTimeClockLib|*/XenRealTimeClockLib.inf to the global
[LibraryClasses]
OvmfPkg/OvmfXen.dsc | 3 ++-
OvmfPkg/OvmfXen.fdf | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index af92ce3ed2..4f626fb5ef 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -199,6 +199,7 @@ [LibraryClasses]
XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
+ RealTimeClockLib|OvmfPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -564,7 +565,7 @@ [Components]
}
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
MdeModulePkg/Universal/Metronome/Metronome.inf
- PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
<LibraryClasses>
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 517a492f14..e6e9e184ef 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -307,7 +307,7 @@ [FV.DXEFV]
INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
INF MdeModulePkg/Universal/Metronome/Metronome.inf
-INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
INF OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (34 preceding siblings ...)
2019-07-04 14:42 ` [PATCH v3 35/35] OvmfPkg/OvmfXen: use RealTimeClockRuntimeDxe from EmbeddedPkg Anthony PERARD
@ 2019-07-05 12:21 ` Laszlo Ersek
2019-07-19 16:42 ` Anthony PERARD
2019-07-05 15:06 ` Laszlo Ersek
2019-07-10 14:12 ` Laszlo Ersek
37 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 12:21 UTC (permalink / raw)
To: devel, anthony.perard
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
Hi Anthony,
On 07/04/19 16:41, Anthony PERARD wrote:
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
>
> Hi,
>
> I've started to create a Xen specific platform, in OvmfPkg/XenOvmf.dsc
> with the goal to make it work on both Xen HVM and Xen PVH.
>
> The first few patches only create the platform and duplicate some code from
> OvmfPkg and the later patches makes OVMF boot in a Xen PVH guest and can boot
> a Linux guest.
>
> After this patch series, I'd like to wait a bit before removing Xen support
> from the OvmfPkg*.dsc, to allow time to switch to the new Xen only platform,
> maybe 1 year.
>
> To build and boot:
>
> To build, simply run OvmfPkg/build.sh -p OvmfPkg/OvmfXen.dsc
> Then use OVMF.fd as a kernel of a pvh guest config file (with xl/libxl).
>
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
The patches on the list are malformed. They have
Content-Transfer-Encoding: quoted-printable
which is fine, in itself; however, they have CR-CR-LF line terminators.
For example, from the first patch:
diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/L=
ibrary/ResetSystemLib/ResetSystemLib.inf
index 7c44f99a5c..2f24dac87f 100644
--- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
+++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -30,4 +30,5 @@ [Packages]
[LibraryClasses]=0D=0D
DebugLib=0D=0D
IoLib=0D=0D
+ PciLib=0D=0D
TimerLib=0D=0D
Note "=0D=0D".
Your other (recent) patches,
- [edk2-devel] [PATCH v2]
OvmfPkg/XenBusDxe: Close XenIoProtocol openned by children
- [edk2-devel] [PATCH]
OvmfPkg/XenBusDxe: Don't call DisconnectController in Stop()
had the same problem; I had to use "--ignore-whitespace" with git-am, to
apply them.
Now, if I try to apply this full set with git-am like that, the first
patch in the series applies, but the second still fails:
> error: corrupt patch at line 23
> Patch failed at 0002 OvmfPkg: Create platform OvmfXen
Based on the email headers, the "iphmx.com" references suggest (via a
google search) "Cisco's Ironport Cloud email service".
I think that email service (MTA) is broken.
I decoded your emails (from quoted-printable to 8-bit plaintext),
removed the "Content-Transfer-Encoding" lines, and replaced '\r\r' with
'\r'. This way, git-am completed (with some "new blank line at EOF"
warnings). Applying the "processed" patches on top of commit
a7c7d21ffa9a, the resultant tree is identical to your tree at
"br.platform-xen-pvh-v3" branch (commit e8795d185875). In addition, I ran
$ git range-diff a7c7d21ffa9a \
xen_pvh_anthony_v3 \
xen_pvh_anthony_v3_from_email
and the only differences reported by that command were the "Message-Id"
tags appended to the commit messages by my "git-am" invocation. (I have
"am.messageid" set to to "true".)
I like to perform this sanity check when a patch series doesn't apply
as-is (without local tweaking) from the list, but there is a remote
topic branch to fetch (i.e. when there are two things I can compare). So
in this case, the sanity check passed fine; I can now look at the
patches themselves.
If you could use a different MTA (or get the current one fixed), that
would be helpful. (Yes, yes: if the edk2 project didn't use CRLF line
terminators, that would be *even more* helpful.)
Thanks
Laszlo
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-05 12:21 ` [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
@ 2019-07-19 16:42 ` Anthony PERARD
2019-07-22 19:09 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-19 16:42 UTC (permalink / raw)
To: Laszlo Ersek
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On Fri, Jul 05, 2019 at 02:21:13PM +0200, Laszlo Ersek wrote:
> The patches on the list are malformed. They have
>
> Content-Transfer-Encoding: quoted-printable
>
> which is fine, in itself; however, they have CR-CR-LF line terminators.
>
> For example, from the first patch:
>
> diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/L=
> ibrary/ResetSystemLib/ResetSystemLib.inf
> index 7c44f99a5c..2f24dac87f 100644
> --- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> +++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> @@ -30,4 +30,5 @@ [Packages]
> [LibraryClasses]=0D=0D
> DebugLib=0D=0D
> IoLib=0D=0D
> + PciLib=0D=0D
> TimerLib=0D=0D
>
> Note "=0D=0D".
>
> Now, if I try to apply this full set with git-am like that, the first
> patch in the series applies, but the second still fails:
>
> > error: corrupt patch at line 23
> > Patch failed at 0002 OvmfPkg: Create platform OvmfXen
>
> Based on the email headers, the "iphmx.com" references suggest (via a
> google search) "Cisco's Ironport Cloud email service".
>
> I think that email service (MTA) is broken.
>
> If you could use a different MTA (or get the current one fixed), that
> would be helpful. (Yes, yes: if the edk2 project didn't use CRLF line
> terminators, that would be *even more* helpful.)
I'm not sure that using a different MTA is going to help. I don't think
I can find a patch on the list that I can apply (without using unix2dos).
I did send a patch to my gmail address, and it looks fine (=0D in the
expected places and nowhere else). So maybe when a patch is sent through
a mailing list, some more formating is done?
Anyway, can I try sending patch encoded in base64 instead of
quoted-printable? That would probably work better.
I found <20190704040731.5303-1-glin@suse.com> on the list that is base64
encoded, that I can easily apply and patchew too.
--
Anthony PERARD
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-19 16:42 ` Anthony PERARD
@ 2019-07-22 19:09 ` Laszlo Ersek
2019-07-23 11:37 ` Anthony PERARD
0 siblings, 1 reply; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-22 19:09 UTC (permalink / raw)
To: Anthony PERARD
Cc: devel, xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On 07/19/19 18:42, Anthony PERARD wrote:
> On Fri, Jul 05, 2019 at 02:21:13PM +0200, Laszlo Ersek wrote:
>> The patches on the list are malformed. They have
>>
>> Content-Transfer-Encoding: quoted-printable
>>
>> which is fine, in itself; however, they have CR-CR-LF line terminators.
>>
>> For example, from the first patch:
>>
>> diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/L=
>> ibrary/ResetSystemLib/ResetSystemLib.inf
>> index 7c44f99a5c..2f24dac87f 100644
>> --- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
>> +++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
>> @@ -30,4 +30,5 @@ [Packages]
>> [LibraryClasses]=0D=0D
>> DebugLib=0D=0D
>> IoLib=0D=0D
>> + PciLib=0D=0D
>> TimerLib=0D=0D
>>
>> Note "=0D=0D".
>>
>> Now, if I try to apply this full set with git-am like that, the first
>> patch in the series applies, but the second still fails:
>>
>>> error: corrupt patch at line 23
>>> Patch failed at 0002 OvmfPkg: Create platform OvmfXen
>>
>> Based on the email headers, the "iphmx.com" references suggest (via a
>> google search) "Cisco's Ironport Cloud email service".
>>
>> I think that email service (MTA) is broken.
>>
>> If you could use a different MTA (or get the current one fixed), that
>> would be helpful. (Yes, yes: if the edk2 project didn't use CRLF line
>> terminators, that would be *even more* helpful.)
>
> I'm not sure that using a different MTA is going to help. I don't think
> I can find a patch on the list that I can apply (without using unix2dos).
> I did send a patch to my gmail address, and it looks fine (=0D in the
> expected places and nowhere else). So maybe when a patch is sent through
> a mailing list, some more formating is done?
>
> Anyway, can I try sending patch encoded in base64 instead of
> quoted-printable? That would probably work better.
>
> I found <20190704040731.5303-1-glin@suse.com> on the list that is base64
> encoded, that I can easily apply and patchew too.
That patch ("[edk2-devel] [PATCH v2] OvmfPkg: use DxeTpmMeasurementLib
if and only if TPM2_ENABLE") worked fine for me as well.
However, Gary confirmed elsewhere that he had to tweak the posting
process manually, for that patch:
http://mid.mail-archive.com/20190704085826.GD32340@GaryWorkstation
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-22 19:09 ` Laszlo Ersek
@ 2019-07-23 11:37 ` Anthony PERARD
2019-07-30 9:03 ` Laszlo Ersek
0 siblings, 1 reply; 90+ messages in thread
From: Anthony PERARD @ 2019-07-23 11:37 UTC (permalink / raw)
To: devel; +Cc: anthony.perard
This is a simple test of email configuration, and how the line ending
survive the different MTAs. (There should only be CRLFs in the hunk, and
LFs everywhere else.)
---
Readme.md | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Readme.md b/Readme.md
index e564c6c09b..5b3eb4442f 100644
--- a/Readme.md
+++ b/Readme.md
@@ -118,6 +118,15 @@ Full-commit-message
Signed-off-by: Contributor Name <contributor@example.com>
```
+# How to properly send a patch to the mailing-lists
+
+tl;dr: That's not possible.
+
+EDK2 got a mix of CRLFs and LFs line ending. Some MTA will probably modify the
+them before reaching the recipient. This patch tests base64 transfer-encoding
+instead of quoted-printable. But the email is probably going to be modified
+anyway...
+
## Notes for sample patch email
* The first line of commit message is taken from the email's subject
--
Anthony PERARD
^ permalink raw reply related [flat|nested] 90+ messages in thread
* Re: [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-23 11:37 ` Anthony PERARD
@ 2019-07-30 9:03 ` Laszlo Ersek
0 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-30 9:03 UTC (permalink / raw)
To: devel, anthony.perard
On 07/23/19 13:37, Anthony PERARD wrote:
> This is a simple test of email configuration, and how the line ending
> survive the different MTAs. (There should only be CRLFs in the hunk, and
> LFs everywhere else.)
>
> ---
> Readme.md | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/Readme.md b/Readme.md
> index e564c6c09b..5b3eb4442f 100644
> --- a/Readme.md
> +++ b/Readme.md
> @@ -118,6 +118,15 @@ Full-commit-message
> Signed-off-by: Contributor Name <contributor@example.com>
> ```
>
> +# How to properly send a patch to the mailing-lists
> +
> +tl;dr: That's not possible.
> +
> +EDK2 got a mix of CRLFs and LFs line ending. Some MTA will probably modify the
> +them before reaching the recipient. This patch tests base64 transfer-encoding
> +instead of quoted-printable. But the email is probably going to be modified
> +anyway...
> +
> ## Notes for sample patch email
>
> * The first line of commit message is taken from the email's subject
>
I'm seeing this test email just now (you didn't CC me). Even now, I
haven't simply noticed the email in my list folder; I'm returning to the
sub-thread deliberately, and that's how I've noticed the posting at the
bottom of the thread.
But, I digress. The reason I'm returning to this sub-thread is to
confirm that your v4 posting (with base64 encoding) applies flawlessly.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (35 preceding siblings ...)
2019-07-05 12:21 ` [edk2-devel] [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
@ 2019-07-05 15:06 ` Laszlo Ersek
2019-07-10 14:12 ` Laszlo Ersek
37 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-05 15:06 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On 07/04/19 16:41, Anthony PERARD wrote:
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
>
> Hi,
>
> I've started to create a Xen specific platform, in OvmfPkg/XenOvmf.dsc
> with the goal to make it work on both Xen HVM and Xen PVH.
>
> The first few patches only create the platform and duplicate some code from
> OvmfPkg and the later patches makes OVMF boot in a Xen PVH guest and can boot
> a Linux guest.
>
> After this patch series, I'd like to wait a bit before removing Xen support
> from the OvmfPkg*.dsc, to allow time to switch to the new Xen only platform,
> maybe 1 year.
>
> To build and boot:
>
> To build, simply run OvmfPkg/build.sh -p OvmfPkg/OvmfXen.dsc
> Then use OVMF.fd as a kernel of a pvh guest config file (with xl/libxl).
>
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
I intend to continue the review with [PATCH v3 11/35], next week.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread
* Re: [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests
2019-07-04 14:41 [PATCH v3 00/35] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
` (36 preceding siblings ...)
2019-07-05 15:06 ` Laszlo Ersek
@ 2019-07-10 14:12 ` Laszlo Ersek
37 siblings, 0 replies; 90+ messages in thread
From: Laszlo Ersek @ 2019-07-10 14:12 UTC (permalink / raw)
To: Anthony PERARD, devel
Cc: xen-devel, Ard Biesheuvel, Jordan Justen, Julien Grall,
Andrew Cooper, Roger Pau Monné
On 07/04/19 16:41, Anthony PERARD wrote:
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
>
> Hi,
>
> I've started to create a Xen specific platform, in OvmfPkg/XenOvmf.dsc
> with the goal to make it work on both Xen HVM and Xen PVH.
>
> The first few patches only create the platform and duplicate some code from
> OvmfPkg and the later patches makes OVMF boot in a Xen PVH guest and can boot
> a Linux guest.
>
> After this patch series, I'd like to wait a bit before removing Xen support
> from the OvmfPkg*.dsc, to allow time to switch to the new Xen only platform,
> maybe 1 year.
>
> To build and boot:
>
> To build, simply run OvmfPkg/build.sh -p OvmfPkg/OvmfXen.dsc
> Then use OVMF.fd as a kernel of a pvh guest config file (with xl/libxl).
>
> Patch series available in this git branch:
> https://xenbits.xen.org/git-http/people/aperard/ovmf.git br.platform-xen-pvh-v3
I believe I've completed the v3 review.
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 90+ messages in thread