Discussion:
[edk2] [PATCH] OvmfPkg: PlatformPei: set SMBIOS entry point version dynamically
Laszlo Ersek
2015-06-19 23:40:51 UTC
Permalink
Git commit 54753b60 (SVN r16870), "MdeModulePkg: Update SMBIOS revision to
3.0." changed PcdSmbiosVersion from 0x0208 to 0x0300. This controls the
version number of the SMBIOS entry point table (and other things) that
"MdeModulePkg/Universal/SmbiosDxe" installs.

Alas, this change breaks older Linux guests, like RHEL-6 (up to RHEL-6.7);
those are limited to 2.x (both in the guest kernel firmware driver, and in
the dmidecode utility).

The v2.1.0+ machine types of QEMU generate SMBIOS payload for the firmware
to install. The payload includes the entry point table ("anchor" table).
OvmfPkg/SmbiosPlatformDxe cannot install the anchor table (because that is
the jurisdiction of the generic "MdeModulePkg/Universal/SmbiosDxe"
driver); however, we can parse the entry point version from QEMU's anchor
table, and instruct "MdeModulePkg/Universal/SmbiosDxe" to adhere to that
version.

On machine types older than v2.1.0, the feature is not available, but
then, should anything in OVMF install SMBIOS tables, version 2.8 is simply
safer / more widely supported than 3.0 -- hence the default 2.8 value for
the dynamic PCD.

We set the PCD in PlatformPei (when not on the S3 resume path), because
that's an easy and certain way to set the PCD before a DXE driver reads
it. This follows the example of PcdEmuVariableNvStoreReserved (which is
read by EmuVariableFvbRuntimeDxe).

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1232876
Cc: Gabriel Somlo <***@cmu.edu>
Cc: Jordan Justen <***@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <***@redhat.com>
---

Notes:
This simple patch is somewhat urgent for RHEL-7.2, please help me by
reviewing it quickly. Thanks!

OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 39 +++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
5 files changed, 47 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0307bca..721495b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
QemuFwCfgLib
MtrrLib
PcdLib
+ BaseMemoryLib

[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -81,6 +82,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress

[Ppis]
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2a1b577..fc98fc3 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,9 +32,11 @@
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/SmBios.h>
#include <OvmfPlatforms.h>

#include "Platform.h"
@@ -380,6 +382,41 @@ DebugDumpCmos (


/**
+ Set the SMBIOS entry point version for the generic SmbiosDxe driver.
+**/
+STATIC
+VOID
+SmbiosVersionInitialization (
+ VOID
+ )
+{
+ FIRMWARE_CONFIG_ITEM Anchor;
+ UINTN AnchorSize;
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+ UINT16 SmbiosVersion;
+
+ if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
+ &AnchorSize)) ||
+ AnchorSize != sizeof QemuAnchor) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (Anchor);
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
+ if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
+ CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
+ return;
+ }
+
+ SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
+ QemuAnchor.MinorVersion);
+ DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
+ SmbiosVersion));
+ PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
+}
+
+
+/**
Perform Platform PEI initialization.

@param FileHandle Handle of the file being invoked.
@@ -429,6 +466,8 @@ InitializePlatform (
PeiFvInitialization ();

MemMapInitialization ();
+
+ SmbiosVersionInitialization ();
}

MiscInitialization ();
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ad476da..b71f751 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -380,6 +380,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480

+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b65ee8..12818e5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -386,6 +386,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480

+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a40d7cb..623033d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -385,6 +385,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480

+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
--
1.8.3.1


------------------------------------------------------------------------------
Jordan Justen
2015-06-21 20:00:12 UTC
Permalink
Post by Laszlo Ersek
Git commit 54753b60 (SVN r16870), "MdeModulePkg: Update SMBIOS revision to
3.0." changed PcdSmbiosVersion from 0x0208 to 0x0300. This controls the
version number of the SMBIOS entry point table (and other things) that
"MdeModulePkg/Universal/SmbiosDxe" installs.
Alas, this change breaks older Linux guests, like RHEL-6 (up to RHEL-6.7);
How does it break them? It seems a bit odd that the firmware could
break the OS by upgrading its SMBIOS version.

Anyway, I think it is good to extract it from QEMU fw-cfg, and I think
for now 2.8 seems a reasonable fall-back default.

I wonder if someone wants to do something similar for Xen?
Post by Laszlo Ersek
those are limited to 2.x (both in the guest kernel firmware driver, and in
the dmidecode utility).
The v2.1.0+ machine types of QEMU generate SMBIOS payload for the firmware
to install. The payload includes the entry point table ("anchor" table).
OvmfPkg/SmbiosPlatformDxe cannot install the anchor table (because that is
the jurisdiction of the generic "MdeModulePkg/Universal/SmbiosDxe"
driver); however, we can parse the entry point version from QEMU's anchor
table, and instruct "MdeModulePkg/Universal/SmbiosDxe" to adhere to that
version.
On machine types older than v2.1.0, the feature is not available, but
then, should anything in OVMF install SMBIOS tables, version 2.8 is simply
safer / more widely supported than 3.0 -- hence the default 2.8 value for
the dynamic PCD.
We set the PCD in PlatformPei (when not on the S3 resume path), because
that's an easy and certain way to set the PCD before a DXE driver reads
it. This follows the example of PcdEmuVariableNvStoreReserved (which is
read by EmuVariableFvbRuntimeDxe).
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1232876
Contributed-under: TianoCore Contribution Agreement 1.0
---
This simple patch is somewhat urgent for RHEL-7.2, please help me by
reviewing it quickly. Thanks!
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 39 +++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
5 files changed, 47 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0307bca..721495b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
QemuFwCfgLib
MtrrLib
PcdLib
+ BaseMemoryLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -81,6 +82,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
[Ppis]
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2a1b577..fc98fc3 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,9 +32,11 @@
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/SmBios.h>
#include <OvmfPlatforms.h>
#include "Platform.h"
@@ -380,6 +382,41 @@ DebugDumpCmos (
/**
+ Set the SMBIOS entry point version for the generic SmbiosDxe driver.
+**/
+STATIC
+VOID
+SmbiosVersionInitialization (
+ VOID
+ )
+{
+ FIRMWARE_CONFIG_ITEM Anchor;
+ UINTN AnchorSize;
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+ UINT16 SmbiosVersion;
+
+ if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
+ &AnchorSize)) ||
+ AnchorSize != sizeof QemuAnchor) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (Anchor);
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
+ if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
+ CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
+ return;
+ }
+
+ SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
+ QemuAnchor.MinorVersion);
+ DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
+ SmbiosVersion));
+ PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
+}
+
+
+/**
Perform Platform PEI initialization.
@param FileHandle Handle of the file being invoked.
@@ -429,6 +466,8 @@ InitializePlatform (
PeiFvInitialization ();
MemMapInitialization ();
+
+ SmbiosVersionInitialization ();
}
MiscInitialization ();
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ad476da..b71f751 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -380,6 +380,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b65ee8..12818e5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -386,6 +386,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a40d7cb..623033d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -385,6 +385,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
--
1.8.3.1
------------------------------------------------------------------------------
Laszlo Ersek
2015-06-22 12:34:20 UTC
Permalink
Post by Jordan Justen
Post by Laszlo Ersek
Git commit 54753b60 (SVN r16870), "MdeModulePkg: Update SMBIOS revision to
3.0." changed PcdSmbiosVersion from 0x0208 to 0x0300. This controls the
version number of the SMBIOS entry point table (and other things) that
"MdeModulePkg/Universal/SmbiosDxe" installs.
Alas, this change breaks older Linux guests, like RHEL-6 (up to RHEL-6.7);
How does it break them? It seems a bit odd that the firmware could
break the OS by upgrading its SMBIOS version.
It breaks them because the SMBIOS 3.0 entry point has a different GUID
in the UEFI Configuration Table, and older guests don't recognize that
GUID. Please refer to this upstream kernel patch (from Ard):

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=e1ccbbc9d5aa01a6c1c9c78acea6515db4f1be71

Kernels that do not have this patch (and probably more dependent code)
won't recognize the SMBIOS 3.0 entry point.

The mantis ticket for the UEFI spec is
<https://mantis.uefi.org/mantis/view.php?id=1191>, resolved in UEFI 2.5.
Post by Jordan Justen
Anyway, I think it is good to extract it from QEMU fw-cfg, and I think
for now 2.8 seems a reasonable fall-back default.
Thanks.
Post by Jordan Justen
I wonder if someone wants to do something similar for Xen?
Thanks a lot, Jordan!
Laszlo
Post by Jordan Justen
Post by Laszlo Ersek
those are limited to 2.x (both in the guest kernel firmware driver, and in
the dmidecode utility).
The v2.1.0+ machine types of QEMU generate SMBIOS payload for the firmware
to install. The payload includes the entry point table ("anchor" table).
OvmfPkg/SmbiosPlatformDxe cannot install the anchor table (because that is
the jurisdiction of the generic "MdeModulePkg/Universal/SmbiosDxe"
driver); however, we can parse the entry point version from QEMU's anchor
table, and instruct "MdeModulePkg/Universal/SmbiosDxe" to adhere to that
version.
On machine types older than v2.1.0, the feature is not available, but
then, should anything in OVMF install SMBIOS tables, version 2.8 is simply
safer / more widely supported than 3.0 -- hence the default 2.8 value for
the dynamic PCD.
We set the PCD in PlatformPei (when not on the S3 resume path), because
that's an easy and certain way to set the PCD before a DXE driver reads
it. This follows the example of PcdEmuVariableNvStoreReserved (which is
read by EmuVariableFvbRuntimeDxe).
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1232876
Contributed-under: TianoCore Contribution Agreement 1.0
---
This simple patch is somewhat urgent for RHEL-7.2, please help me by
reviewing it quickly. Thanks!
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 39 +++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
5 files changed, 47 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0307bca..721495b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
QemuFwCfgLib
MtrrLib
PcdLib
+ BaseMemoryLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -81,6 +82,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
[Ppis]
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2a1b577..fc98fc3 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,9 +32,11 @@
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/SmBios.h>
#include <OvmfPlatforms.h>
#include "Platform.h"
@@ -380,6 +382,41 @@ DebugDumpCmos (
/**
+ Set the SMBIOS entry point version for the generic SmbiosDxe driver.
+**/
+STATIC
+VOID
+SmbiosVersionInitialization (
+ VOID
+ )
+{
+ FIRMWARE_CONFIG_ITEM Anchor;
+ UINTN AnchorSize;
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+ UINT16 SmbiosVersion;
+
+ if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
+ &AnchorSize)) ||
+ AnchorSize != sizeof QemuAnchor) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (Anchor);
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
+ if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
+ CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
+ return;
+ }
+
+ SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
+ QemuAnchor.MinorVersion);
+ DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
+ SmbiosVersion));
+ PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
+}
+
+
+/**
Perform Platform PEI initialization.
@param FileHandle Handle of the file being invoked.
@@ -429,6 +466,8 @@ InitializePlatform (
PeiFvInitialization ();
MemMapInitialization ();
+
+ SmbiosVersionInitialization ();
}
MiscInitialization ();
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ad476da..b71f751 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -380,6 +380,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b65ee8..12818e5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -386,6 +386,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a40d7cb..623033d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -385,6 +385,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
--
1.8.3.1
Laszlo Ersek
2015-06-22 17:19:31 UTC
Permalink
Post by Laszlo Ersek
Post by Jordan Justen
Post by Laszlo Ersek
Git commit 54753b60 (SVN r16870), "MdeModulePkg: Update SMBIOS revision to
3.0." changed PcdSmbiosVersion from 0x0208 to 0x0300. This controls the
version number of the SMBIOS entry point table (and other things) that
"MdeModulePkg/Universal/SmbiosDxe" installs.
Alas, this change breaks older Linux guests, like RHEL-6 (up to RHEL-6.7);
How does it break them? It seems a bit odd that the firmware could
break the OS by upgrading its SMBIOS version.
It breaks them because the SMBIOS 3.0 entry point has a different GUID
in the UEFI Configuration Table, and older guests don't recognize that
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=e1ccbbc9d5aa01a6c1c9c78acea6515db4f1be71
Kernels that do not have this patch (and probably more dependent code)
won't recognize the SMBIOS 3.0 entry point.
The mantis ticket for the UEFI spec is
<https://mantis.uefi.org/mantis/view.php?id=1191>, resolved in UEFI 2.5.
Thanks again for the reviews / acks; I worked the above explanation into
the commit message and committed the patch as SVN r17676.

Cheers
Laszlo
Post by Laszlo Ersek
Post by Jordan Justen
Anyway, I think it is good to extract it from QEMU fw-cfg, and I think
for now 2.8 seems a reasonable fall-back default.
Thanks.
Post by Jordan Justen
I wonder if someone wants to do something similar for Xen?
Thanks a lot, Jordan!
Laszlo
Post by Jordan Justen
Post by Laszlo Ersek
those are limited to 2.x (both in the guest kernel firmware driver, and in
the dmidecode utility).
The v2.1.0+ machine types of QEMU generate SMBIOS payload for the firmware
to install. The payload includes the entry point table ("anchor" table).
OvmfPkg/SmbiosPlatformDxe cannot install the anchor table (because that is
the jurisdiction of the generic "MdeModulePkg/Universal/SmbiosDxe"
driver); however, we can parse the entry point version from QEMU's anchor
table, and instruct "MdeModulePkg/Universal/SmbiosDxe" to adhere to that
version.
On machine types older than v2.1.0, the feature is not available, but
then, should anything in OVMF install SMBIOS tables, version 2.8 is simply
safer / more widely supported than 3.0 -- hence the default 2.8 value for
the dynamic PCD.
We set the PCD in PlatformPei (when not on the S3 resume path), because
that's an easy and certain way to set the PCD before a DXE driver reads
it. This follows the example of PcdEmuVariableNvStoreReserved (which is
read by EmuVariableFvbRuntimeDxe).
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1232876
Contributed-under: TianoCore Contribution Agreement 1.0
---
This simple patch is somewhat urgent for RHEL-7.2, please help me by
reviewing it quickly. Thanks!
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 39 +++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
5 files changed, 47 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0307bca..721495b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
QemuFwCfgLib
MtrrLib
PcdLib
+ BaseMemoryLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -81,6 +82,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
[Ppis]
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2a1b577..fc98fc3 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,9 +32,11 @@
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/SmBios.h>
#include <OvmfPlatforms.h>
#include "Platform.h"
@@ -380,6 +382,41 @@ DebugDumpCmos (
/**
+ Set the SMBIOS entry point version for the generic SmbiosDxe driver.
+**/
+STATIC
+VOID
+SmbiosVersionInitialization (
+ VOID
+ )
+{
+ FIRMWARE_CONFIG_ITEM Anchor;
+ UINTN AnchorSize;
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+ UINT16 SmbiosVersion;
+
+ if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
+ &AnchorSize)) ||
+ AnchorSize != sizeof QemuAnchor) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (Anchor);
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
+ if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
+ CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
+ return;
+ }
+
+ SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
+ QemuAnchor.MinorVersion);
+ DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
+ SmbiosVersion));
+ PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
+}
+
+
+/**
Perform Platform PEI initialization.
@param FileHandle Handle of the file being invoked.
@@ -429,6 +466,8 @@ InitializePlatform (
PeiFvInitialization ();
MemMapInitialization ();
+
+ SmbiosVersionInitialization ();
}
MiscInitialization ();
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ad476da..b71f751 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -380,6 +380,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b65ee8..12818e5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -386,6 +386,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a40d7cb..623033d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -385,6 +385,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
--
1.8.3.1
------------------------------------------------------------------------------
Monitor 25 network devices or servers for free with OpManager!
OpManager is web-based network management software that monitors
network devices and physical & virtual servers, alerts via email & sms
for fault. Monitor 25 devices for free with no restriction. Download now
http://ad.doubleclick.net/ddm/clk/292181274;119417398;o
_______________________________________________
edk2-devel mailing list
https://lists.sourceforge.net/lists/listinfo/edk2-devel
Gabriel L. Somlo
2015-06-22 15:12:34 UTC
Permalink
Post by Laszlo Ersek
Git commit 54753b60 (SVN r16870), "MdeModulePkg: Update SMBIOS revision to
3.0." changed PcdSmbiosVersion from 0x0208 to 0x0300. This controls the
version number of the SMBIOS entry point table (and other things) that
"MdeModulePkg/Universal/SmbiosDxe" installs.
Alas, this change breaks older Linux guests, like RHEL-6 (up to RHEL-6.7);
those are limited to 2.x (both in the guest kernel firmware driver, and in
the dmidecode utility).
The v2.1.0+ machine types of QEMU generate SMBIOS payload for the firmware
to install. The payload includes the entry point table ("anchor" table).
OvmfPkg/SmbiosPlatformDxe cannot install the anchor table (because that is
the jurisdiction of the generic "MdeModulePkg/Universal/SmbiosDxe"
driver); however, we can parse the entry point version from QEMU's anchor
table, and instruct "MdeModulePkg/Universal/SmbiosDxe" to adhere to that
version.
On machine types older than v2.1.0, the feature is not available, but
then, should anything in OVMF install SMBIOS tables, version 2.8 is simply
safer / more widely supported than 3.0 -- hence the default 2.8 value for
the dynamic PCD.
We set the PCD in PlatformPei (when not on the S3 resume path), because
that's an easy and certain way to set the PCD before a DXE driver reads
it. This follows the example of PcdEmuVariableNvStoreReserved (which is
read by EmuVariableFvbRuntimeDxe).
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1232876
Acked-by: Gabriel Somlo <***@cmu.edu>

Thanks much,
--Gabriel
Post by Laszlo Ersek
Contributed-under: TianoCore Contribution Agreement 1.0
---
This simple patch is somewhat urgent for RHEL-7.2, please help me by
reviewing it quickly. Thanks!
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/Platform.c | 39 +++++++++++++++++++++++++++++++++++++
OvmfPkg/OvmfPkgIa32.dsc | 2 ++
OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++
OvmfPkg/OvmfPkgX64.dsc | 2 ++
5 files changed, 47 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0307bca..721495b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -58,6 +58,7 @@ [LibraryClasses]
QemuFwCfgLib
MtrrLib
PcdLib
+ BaseMemoryLib
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -81,6 +82,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
[Ppis]
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2a1b577..fc98fc3 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -32,9 +32,11 @@
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/SmBios.h>
#include <OvmfPlatforms.h>
#include "Platform.h"
@@ -380,6 +382,41 @@ DebugDumpCmos (
/**
+ Set the SMBIOS entry point version for the generic SmbiosDxe driver.
+**/
+STATIC
+VOID
+SmbiosVersionInitialization (
+ VOID
+ )
+{
+ FIRMWARE_CONFIG_ITEM Anchor;
+ UINTN AnchorSize;
+ SMBIOS_TABLE_ENTRY_POINT QemuAnchor;
+ UINT16 SmbiosVersion;
+
+ if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smbios/smbios-anchor", &Anchor,
+ &AnchorSize)) ||
+ AnchorSize != sizeof QemuAnchor) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (Anchor);
+ QemuFwCfgReadBytes (AnchorSize, &QemuAnchor);
+ if (CompareMem (QemuAnchor.AnchorString, "_SM_", 4) != 0 ||
+ CompareMem (QemuAnchor.IntermediateAnchorString, "_DMI_", 5) != 0) {
+ return;
+ }
+
+ SmbiosVersion = (UINT16)(QemuAnchor.MajorVersion << 8 |
+ QemuAnchor.MinorVersion);
+ DEBUG ((EFI_D_INFO, "%a: SMBIOS version from QEMU: 0x%04x\n", __FUNCTION__,
+ SmbiosVersion));
+ PcdSet16 (PcdSmbiosVersion, SmbiosVersion);
+}
+
+
+/**
Perform Platform PEI initialization.
@param FileHandle Handle of the file being invoked.
@@ -429,6 +466,8 @@ InitializePlatform (
PeiFvInitialization ();
MemMapInitialization ();
+
+ SmbiosVersionInitialization ();
}
MiscInitialization ();
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index ad476da..b71f751 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -380,6 +380,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6b65ee8..12818e5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -386,6 +386,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a40d7cb..623033d 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -385,6 +385,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
--
1.8.3.1
Loading...