On 2015-07-30 10:09:34, Laszlo Ersek wrote:
> (Sigh, I left off the list address. This should be discussed publicly.
> Resending.)
> 
> Clearly, the SMBIOS patches I posted and got committed last time are not
> good enough. That's because the SMBIOS 3.0 entry point is structurally
> different from the prior versions (because why not). Therefore, now that
> Wei has QEMU generate SMBIOS 3.0 payload for the firmware, the checks we
> currently have in place, fail.
> 
> (First and foremost, the *size* of the 3.0 entry point is different from
> that of the 2.8 one. We correctly catch this, but we incorrectly don't
> recognize 3.0.)
> 
> I can write the code for telling apart 2.8 from 3.0; that's not the
> problem. The problem is that this code would have to be triplicated, as
> things currently stand:
> 
> (1) "ArmVirtPkg/QemuFwCfgToPcdDxe/QemuFwCfgToPcd.c" sets
>     PcdSmbiosVersion for "MdeModulePkg/Universal/SmbiosDxe" in the
>     ArmVirtPkg build, early in the DXE phase,
> 
> (2) "OvmfPkg/PlatformPei/Platform.c" sets the same PCD for the same
>     generic driver in the OvmfPkg build, in the PEI phase,
> 
> (3) "OvmfPkg/SmbiosPlatformDxe/Qemu.c" verifies the entry point again,
>     and fetches the actual tables. (Note that
>     (TablesSize != QemuAnchor.TableLength) is checked too, so there is a
>     cross-dependency between the two blobs, the entry point and the
>     actual tables.)
> 
> Now, the current triplication we have is simplistic, so it shouldn't be
> a large problem. But, if I need to add smarts for detecting v2 versus
> v3, I would hate to triplicate that logic too. This is what code sites
> (1) and (2) both should do, for determining PcdSmbiosVersion:
> 
> - Find "etc/smbios/smbios-anchor". If it is missing, bail.
> - Compare the size of that fw-cfg blob against SMBIOS_TABLE_ENTRY_POINT.
>     - If it is a match, perform the current _SM_ and _DMI_ checks.
>     - If they fail, bail.
>     - If they match, check that QemuAnchor.MajorVersion is actually 2.
>     - If that fails, bail.
>     - If it matches, set PcdSmbiosVersion to 0x02__.
> - Otherwise, compare the size of the anchor blob against
>   SMBIOS_TABLE_3_0_ENTRY_POINT.
>     - If it is a match, perform the (new) _SM3_ check.
>     - If it fails, bail.
>     - Check that MajorVersion (which now lives at a different offset) is
>       3.
>     - If that fails, bail.
>     - If it matches, set PcdSmbiosVersion to 0x03__.
> - Otherwise, bail.
> 
> In (3):
> - repeat all of the above, except do not *set* the PCD -- enforce it
>   instead. ASSERT() that the PCD already has the right value (because
>   at this point MdeModulePkg/Universal/SmbiosDxe is expected to have
>   been dispatched, and consumed the PCD).
> - If the version is 2, then compare TableLength == tables blob size.
>   If it fails, return NULL; otherwise return the tables.
> - If the version is 3, then compare TableMaximumSize >= tables blob
>   size. If it fails, return NULL; otherwise return the tables.
> - If the version is something different, return NULL.
> 
> As I said, this can be coded as-written, but I strongly dislike the code
> triplication, and I expect you guys will too. So what do you propose? I
> could extract a tiny BASE library (a single function) that:
> - depends on QemuFwCfgLib
> - takes a BOOLEAN parameter that tells it whether to set the PCD, or
>   check and enforce the PCD
> - return the detected SMBIOS version (2, 3, or "missing/unknown")
> 
> Then I could use this function in sites (1) and (2) for setting the PCD,
> and then use it in (3) for enforcing the PCD, and based on the returned
> SMBIOS version, perform the version-specific tables blob size check too.

Would it help if you used a NULL library with a constructor to set
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion?

  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
    <LibraryClasses>
      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
  }

I'm not sure about the enforce part, but maybe this could allow you to
also share some code between detect & enforce:

  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf {
    <LibraryClasses>
      NULL|OvmfPkg/Library/SmbiosVersionLib/ValidateSmbiosVersionLib.inf
  }

But, I'm a little skeptical of the necessity of this second one...

-Jordan

> Small problem: you are going to hate me for introducing a
> single-function library *class*.
> 
> So how do I share *one function* between different *phase* modules of
> different top-level packages? Should we introduce BaseCrapLib ^W
> BaseUtilityLib, and just keep throwing such functions in there?
> 
> If so, what names (pathnames, basenames, library class and instance
> names etc) do you recommend?
> 
> Thanks
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to