Message ID | 20190409110844.14746-13-anthony.perard@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Specific platform to run OVMF in Xen PVH and HVM guests | expand |
On 04/09/19 13:08, Anthony PERARD wrote: > 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. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> > --- > OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 3 + > OvmfPkg/Include/Guid/XenInfo.h | 4 + > OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h | 159 ++++++++++++++++++++ > OvmfPkg/XenPlatformPei/Xen.c | 26 ++++ > 4 files changed, 192 insertions(+) > > diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf > index c8d25c115f..1870e39208 100644 > --- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf > +++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf > @@ -91,6 +91,9 @@ [Pcd] > gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy > gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress > > + gUefiOvmfPkgTokenSpaceGuid.PcdXenStartOfDayStructPtr > + gUefiOvmfPkgTokenSpaceGuid.PcdXenStartOfDayStructPtrSize > + > [FixedPcd] > gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress > > diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h > index 5d4579f244..d9c09080bb 100644 > --- a/OvmfPkg/Include/Guid/XenInfo.h > +++ b/OvmfPkg/Include/Guid/XenInfo.h > @@ -31,6 +31,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..71bff7dc37 > --- /dev/null > +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h > @@ -0,0 +1,159 @@ > +/* > + * Permission is hereby granted, free of charge, to any person obtaining a copy > + * of this software and associated documentation files (the "Software"), to > + * deal in the Software without restriction, including without limitation the > + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or > + * sell copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE > + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * (1) Rather than this license block, please use SPDX-License-Identifier: MIT instead -- please refer to <https://bugzilla.tianocore.org/show_bug.cgi?id=1654>. > + * 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 df906b6be5..fb01094ba9 100644 > --- a/OvmfPkg/XenPlatformPei/Xen.c > +++ b/OvmfPkg/XenPlatformPei/Xen.c > @@ -31,6 +31,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" > @@ -92,6 +93,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); > @@ -125,6 +127,30 @@ 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(PcdXenStartOfDayStructPtr); (2) missing space after PcdGet32 > + // > + // That magic value is "XPVH", and it is written in > + // XenResetVector/Ia32/XenPVHMain.asm > + // > + if (PVHResetVectorData[1] == 0x48565058) { (3) If possible, please use the SIGNATURE_32() macro here. > + 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, > With the above updated Acked-by: Laszlo Ersek <lersek@redhat.com> Thanks Laszlo
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf index c8d25c115f..1870e39208 100644 --- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf +++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf @@ -91,6 +91,9 @@ [Pcd] gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress + gUefiOvmfPkgTokenSpaceGuid.PcdXenStartOfDayStructPtr + gUefiOvmfPkgTokenSpaceGuid.PcdXenStartOfDayStructPtrSize + [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h index 5d4579f244..d9c09080bb 100644 --- a/OvmfPkg/Include/Guid/XenInfo.h +++ b/OvmfPkg/Include/Guid/XenInfo.h @@ -31,6 +31,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..71bff7dc37 --- /dev/null +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h @@ -0,0 +1,159 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * 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 df906b6be5..fb01094ba9 100644 --- a/OvmfPkg/XenPlatformPei/Xen.c +++ b/OvmfPkg/XenPlatformPei/Xen.c @@ -31,6 +31,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" @@ -92,6 +93,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); @@ -125,6 +127,30 @@ 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(PcdXenStartOfDayStructPtr); + // + // That magic value is "XPVH", and it is written in + // XenResetVector/Ia32/XenPVHMain.asm + // + if (PVHResetVectorData[1] == 0x48565058) { + 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,
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. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 3 + OvmfPkg/Include/Guid/XenInfo.h | 4 + OvmfPkg/Include/IndustryStandard/Xen/arch-x86/hvm/start_info.h | 159 ++++++++++++++++++++ OvmfPkg/XenPlatformPei/Xen.c | 26 ++++ 4 files changed, 192 insertions(+)