From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) by mx.groups.io with SMTP id smtpd.web11.13233.1614609144885336770 for ; Mon, 01 Mar 2021 06:32:25 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@9elements.com header.s=google header.b=beeHJ/PQ; spf=pass (domain: 9elements.com, ip: 209.85.128.54, mailfrom: patrick.rudolph@9elements.com) Received: by mail-wm1-f54.google.com with SMTP id m1so14736183wml.2 for ; Mon, 01 Mar 2021 06:32:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9elements.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=aLmHsZfdShhFqaktkhzvVOAzzVQ26vH289PPDuRKz68=; b=beeHJ/PQ63ipjqHGyQ508UiZGVCR/5YggEGWRzwlrWRI3Nguj9tTlJN5V64y5IIKIm DqUVwXaOpYrM5CQpmn1ot446FvHKuRZ6g0BYMa2NFRw4oMS3Aj/h1sKBlv9gp46hcH19 Av9BgcsyJUAbuMuGkcRKvcssGrbpPU5njZTG/bnWqMqdDR3SwEJsthrKMZXk/874KjCh w9izM/lmKetsWhFv1E8GxJhH67gukjtsr/hNjAmuCIgnYy+xpyCTFl1/r813DnA2fl6v o3OhGz6663+x1oaVV8Z2/lFL3UDkTS4+4T5Vt4ATC4w0ErqkYeABTP+44XOPsQa6ln3w dyOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=aLmHsZfdShhFqaktkhzvVOAzzVQ26vH289PPDuRKz68=; b=Hu7gVlMCUW7ovxibaUwVviA2nh9atWLjRtlUj8jXC+bX2RSMocHgxGeL0swfhRUf2L 3EqnoPDeWF3uF21S4MFkKCjzssqRMpvmNhKGSQ4z/Hd+bMuJtgVNE7fKsdBfxkS6z4eP eoxRPKGKTPm+LiIAYVe//Jp+oSVvucBzGXqE4GcprYue66fkgehIJqRtKf14M6tgYtRX DMMwQOlNvwDACRbMxX97QqX2g+CGnE2B36FGqK53DYJ3zw3ZxzMU5DS0S2g398OVdWBz H+JMcjYu4zbANFybFAMPMRoM+uIJcuTHvkKFBWwx7y8dmdctYe/9OYEeXXFQaJJOXVXN U5Nw== X-Gm-Message-State: AOAM532aO/g/uNmT5Nj2pqiIsRL/0GBMhZdXNkEu8L/WmKd0ssTFVTq6 L0RMqI17bhawpMhGD0WjYTE4I7E1MJz+MfY1 X-Google-Smtp-Source: ABdhPJwTvPoJDKoBjUqZXIBTFtP9uANkaQxNFWGGiNM9npmxubXHrvA2lsvD/YpmJ3XSNuiD1Kp/mg== X-Received: by 2002:a1c:195:: with SMTP id 143mr3796054wmb.81.1614609143210; Mon, 01 Mar 2021 06:32:23 -0800 (PST) Return-Path: Received: from rudolphp-notebook.sr1.9esec.dev (b2b-78-94-0-50.unitymedia.biz. [78.94.0.50]) by smtp.gmail.com with ESMTPSA id x18sm24056371wrs.16.2021.03.01.06.32.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Mar 2021 06:32:22 -0800 (PST) From: "Patrick Rudolph" To: devel@edk2.groups.io Cc: dandan.bi@intel.com, star.zeng@intel.com, zhichao.gao@intel.com, benjamin.you@intel.com, philipp.deppenwiese@9elements.com, maurice.ma@intel.com, guo.dong@intel.com Subject: [PATCH - resend] MdeModulePkg/Universal/SmbiosDxe: Scan for existing tables Date: Mon, 1 Mar 2021 15:32:21 +0100 Message-Id: <20210301143221.2775162-1-patrick.rudolph@9elements.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable The default EfiSmbiosProtocol operates on an empty SMBIOS table. The SMBIOS tables are provided by the bootloader on UefiPayloadPkg. Scan for existing tables in SmbiosDxe and load them if they seem valid. This fixes the settings menu not showing any hardware information, instead only "0 MB RAM" was displayed. Tests showed that the OS can still see the SMBIOS tables. Signed-off-by: Patrick Rudolph --- MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c | 223 +++++++++++++++++++- 1 file changed, 221 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c b/MdeModulePkg/Un= iversal/SmbiosDxe/SmbiosDxe.c index 3cdb0b1ed7..958a249cf9 100644 --- a/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c +++ b/MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c @@ -1408,6 +1408,177 @@ SmbiosTableConstruction ( }=0D }=0D =0D +/**=0D + Validates a SMBIOS 2.0 table entry point.=0D +=0D + @param EntryPointStructure The SMBIOS_TABLE_ENTRY_POINT to validate.= =0D +=0D + @retval TRUE SMBIOS table entry point is valid.=0D + @retval FALSE SMBIOS table entry point is malformed.=0D +=0D +**/=0D +STATIC=0D +BOOLEAN=0D +ValidateSmbios20Table(=0D + IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure=0D +) {=0D + UINT8 Checksum;=0D +=0D + if (CompareMem (EntryPointStructure->AnchorString, "_SM_", 4) !=3D 0) {= =0D + return FALSE;=0D + }=0D + if (EntryPointStructure->EntryPointLength < 0x1E) {=0D + return FALSE;=0D + }=0D + if (EntryPointStructure->MajorVersion < 2) {=0D + return FALSE;=0D + }=0D + if (EntryPointStructure->SmbiosBcdRevision > 0 &&=0D + (EntryPointStructure->SmbiosBcdRevision >> 4) < 2) {=0D + return FALSE;=0D + }=0D + if (EntryPointStructure->TableLength =3D=3D 0) {=0D + return FALSE;=0D + }=0D + if (EntryPointStructure->TableAddress =3D=3D 0 ||=0D + EntryPointStructure->TableAddress =3D=3D ~0) {=0D + return FALSE;=0D + }=0D +=0D + Checksum =3D CalculateSum8((UINT8 *) EntryPointStructure,=0D + EntryPointStructure->EntryPointLength);=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + Checksum =3D CalculateSum8((UINT8 *) EntryPointStructure + 0x10,=0D + EntryPointStructure->EntryPointLength - 0x10);=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Validates a SMBIOS 3.0 table entry point.=0D +=0D + @param Smbios30EntryPointStructure The SMBIOS_TABLE_3_0_ENTRY_POINT t= o validate.=0D +=0D + @retval TRUE SMBIOS table entry point is valid.=0D + @retval FALSE SMBIOS table entry point is malformed.=0D +=0D +**/=0D +STATIC=0D +BOOLEAN=0D +ValidateSmbios30Table(=0D + IN SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios30EntryPointStructure=0D +) {=0D + UINT8 Checksum;=0D +=0D + if (CompareMem (Smbios30EntryPointStructure->AnchorString, "_SM3_", 5) != =3D 0) {=0D + return FALSE;=0D + }=0D + if (Smbios30EntryPointStructure->EntryPointLength < 0x18) {=0D + return FALSE;=0D + }=0D + if (Smbios30EntryPointStructure->MajorVersion < 3) {=0D + return FALSE;=0D + }=0D + if (Smbios30EntryPointStructure->TableMaximumSize =3D=3D 0) {=0D + return FALSE;=0D + }=0D + if (Smbios30EntryPointStructure->TableAddress =3D=3D 0 ||=0D + Smbios30EntryPointStructure->TableAddress =3D=3D ~0) {=0D + return FALSE;=0D + }=0D +=0D + Checksum =3D CalculateSum8((UINT8 *) Smbios30EntryPointStructure,=0D + Smbios30EntryPointStructure->EntryPointLength);=0D + if (Checksum !=3D 0) {=0D + return FALSE;=0D + }=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Parse an existing SMBIOS table and insert it using SmbiosAdd.=0D +=0D + @param ImageHandle The EFI_HANDLE to this driver.=0D + @param Smbios The SMBIOS table to parse.=0D + @param Length The length of the SMBIOS table.=0D +=0D + @retval EFI_SUCCESS SMBIOS table was parsed and installed.=0D + @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system= resources.=0D +=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +ParseAndAddExistingSmbiosTable(=0D + IN EFI_HANDLE ImageHandle,=0D + IN SMBIOS_STRUCTURE_POINTER Smbios,=0D + IN UINTN Length=0D +) {=0D + EFI_STATUS Status;=0D + CHAR8 *String;=0D + EFI_SMBIOS_HANDLE SmbiosHandle;=0D + SMBIOS_STRUCTURE_POINTER SmbiosEnd;=0D +=0D + SmbiosEnd.Raw =3D Smbios.Raw + Length;=0D +=0D + do {=0D + // Check for end marker=0D + if (Smbios.Hdr->Type =3D=3D 127) {=0D + break;=0D + }=0D +=0D + // Install the table=0D + SmbiosHandle =3D SMBIOS_HANDLE_PI_RESERVED;=0D + Status =3D SmbiosAdd (=0D + &mPrivateData.Smbios,=0D + ImageHandle,=0D + &SmbiosHandle,=0D + Smbios.Hdr=0D + );=0D +=0D + ASSERT_EFI_ERROR (Status);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + //=0D + // Go to the next SMBIOS structure. Each SMBIOS structure may include = 2 parts:=0D + // 1. Formatted section; 2. Unformatted string section. So, 2 steps ar= e needed=0D + // to skip one SMBIOS structure.=0D + //=0D +=0D + //=0D + // Step 1: Skip over formatted section.=0D + //=0D + String =3D (CHAR8 *) (Smbios.Raw + Smbios.Hdr->Length);=0D +=0D + //=0D + // Step 2: Skip over unformatted string section.=0D + //=0D + do {=0D + //=0D + // Each string is terminated with a NULL(00h) BYTE and the sets of s= trings=0D + // is terminated with an additional NULL(00h) BYTE.=0D + //=0D + for ( ; *String !=3D 0; String++) {=0D + }=0D +=0D + if (*(UINT8*)++String =3D=3D 0) {=0D + //=0D + // Pointer to the next SMBIOS structure.=0D + //=0D + Smbios.Raw =3D (UINT8 *)++String;=0D + break;=0D + }=0D + } while (TRUE);=0D + } while (Smbios.Raw < SmbiosEnd.Raw);=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D /**=0D =0D Driver to produce Smbios protocol and pre-allocate 1 page for the final = SMBIOS table.=0D @@ -1426,7 +1597,10 @@ SmbiosDriverEntryPoint ( IN EFI_SYSTEM_TABLE *SystemTable=0D )=0D {=0D - EFI_STATUS Status;=0D + EFI_STATUS Status;=0D + SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;=0D + SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios30Table;=0D + SMBIOS_STRUCTURE_POINTER Smbios;=0D =0D mPrivateData.Signature =3D SMBIOS_INSTANCE_SIGNATURE;=0D mPrivateData.Smbios.Add =3D SmbiosAdd;=0D @@ -1450,6 +1624,51 @@ SmbiosDriverEntryPoint ( EFI_NATIVE_INTERFACE,=0D &mPrivateData.Smbios=0D );=0D + //=0D + // Scan for existing SMBIOS tables installed by bootloader=0D + //=0D + Status =3D EfiGetSystemConfigurationTable (=0D + &gEfiSmbios3TableGuid,=0D + (VOID **) &Smbios30Table=0D + );=0D + if (!EFI_ERROR (Status) && ValidateSmbios30Table(Smbios30Table)) {=0D + Smbios.Raw =3D AllocatePool(Smbios30Table->TableMaximumSize);=0D + if (!Smbios.Raw) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D + //=0D + // Backup old table in case it gets overwritten while parsing it=0D + //=0D + CopyMem (Smbios.Raw, (VOID *)Smbios30Table, Smbios30Table->TableMaximu= mSize);=0D + Status =3D ParseAndAddExistingSmbiosTable(ImageHandle, Smbios, Smbios3= 0Table->TableMaximumSize);=0D + FreePool(Smbios.Raw);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "SmbiosDriverEntryPoint: Failed to parse preins= talled tables\n"));=0D + Status =3D EFI_SUCCESS;=0D + }=0D + }=0D +=0D + Status =3D EfiGetSystemConfigurationTable (=0D + &gEfiSmbiosTableGuid,=0D + (VOID **) &SmbiosTable=0D + );=0D + if (!EFI_ERROR (Status) && ValidateSmbios20Table(SmbiosTable)) {=0D + Smbios.Raw =3D AllocatePool(SmbiosTable->TableLength);=0D + if (!Smbios.Raw) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D + //=0D + // Backup old table in case it gets overwritten while parsing it=0D + //=0D + CopyMem (Smbios.Raw, (VOID *)(UINTN)SmbiosTable->TableAddress, SmbiosT= able->TableLength);=0D =0D - return Status;=0D + Status =3D ParseAndAddExistingSmbiosTable(ImageHandle, Smbios, SmbiosT= able->TableLength);=0D + FreePool(Smbios.Raw);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "SmbiosDriverEntryPoint: Failed to parse preins= talled tables\n"));=0D + Status =3D EFI_SUCCESS;=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D }=0D --=20 2.26.2