diff mbox

[v2,Ping] SMBIOS: Upgrade Type17 to v2.3, add Type2

Message ID 20140217160947.GO29329@ERROL.INI.CMU.EDU
State New
Headers show

Commit Message

Gabriel L. Somlo Feb. 17, 2014, 4:09 p.m. UTC
Add v2.3 fields to Type 17 (Memory Device) structure.
Add Type 2 (Baseboard) structure.

"About This Mac" on OS X guests will crash and restart the GUI if
Type 17 structures are not compliant with at least v2.3 of the
SMBIOS/DMI spec.

OS X 10.7 and 10.8 will panic during boot if a Type 2 (Baseboard)
structure is not present in the SMBIOS.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
---

On Fri, Feb 07, 2014 at 04:37:58PM +0100, Paolo Bonzini wrote:
>Il 06/02/2014 14:38, Gabriel L. Somlo ha scritto:
>>On Wed, Feb 05, 2014 at 08:02:25PM -0500, Kevin O'Connor wrote:
>>> Thanks.  In general, though, it is preferred to make smbios changes at
>>> the QEMU layer.  Indeed, going forward, I'd like to see all the smbios
>>> stuff moved up to QEMU.
>>>
>>> Is there something in these two patches that can't be done in QEMU?
>>
>> But anyhow, right now QEMU seems to be making relatively minor tweaks
>> to something that's firmly at home in SeaBIOS, which is why I sent my
>> patches to the latter...
>
>Yeah, that's correct. There's really no particular hook in QEMU to do this.

Would it be OK to apply this in SeaBIOS now, so that 1. it can be
useful until whenever SMBIOS gets transferred/absorbed into QEMU,
and 2. it won't fall through the cracks when that transition happens ?

Thanks much,
   Gabriel

 src/fw/smbios.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/std/smbios.h | 22 ++++++++++++++++++++++
 2 files changed, 64 insertions(+)

Comments

Kevin O'Connor Feb. 17, 2014, 8:33 p.m. UTC | #1
On Mon, Feb 17, 2014 at 11:09:48AM -0500, Gabriel L. Somlo wrote:
> On Fri, Feb 07, 2014 at 04:37:58PM +0100, Paolo Bonzini wrote:
> >Il 06/02/2014 14:38, Gabriel L. Somlo ha scritto:
> >>On Wed, Feb 05, 2014 at 08:02:25PM -0500, Kevin O'Connor wrote:
> >>> Thanks.  In general, though, it is preferred to make smbios changes at
> >>> the QEMU layer.  Indeed, going forward, I'd like to see all the smbios
> >>> stuff moved up to QEMU.
> >>>
> >>> Is there something in these two patches that can't be done in QEMU?
> >>
> >> But anyhow, right now QEMU seems to be making relatively minor tweaks
> >> to something that's firmly at home in SeaBIOS, which is why I sent my
> >> patches to the latter...
> >
> >Yeah, that's correct. There's really no particular hook in QEMU to do this.
> 
> Would it be OK to apply this in SeaBIOS now, so that 1. it can be
> useful until whenever SMBIOS gets transferred/absorbed into QEMU,
> and 2. it won't fall through the cracks when that transition happens ?

Unfortunately, if we change the smbios in SeaBIOS, it will show up on
all machine types that use the new version of SeaBIOS.  We've had
issues with this type of change before as various OSes react
differently to the change.

Gerd, what's your take on this change?

-Kevin
Gerd Hoffmann Feb. 18, 2014, 10:21 a.m. UTC | #2
On Mo, 2014-02-17 at 15:33 -0500, Kevin O'Connor wrote:
> On Mon, Feb 17, 2014 at 11:09:48AM -0500, Gabriel L. Somlo wrote:
> > On Fri, Feb 07, 2014 at 04:37:58PM +0100, Paolo Bonzini wrote:
> > >Il 06/02/2014 14:38, Gabriel L. Somlo ha scritto:
> > >>On Wed, Feb 05, 2014 at 08:02:25PM -0500, Kevin O'Connor wrote:
> > >>> Thanks.  In general, though, it is preferred to make smbios changes at
> > >>> the QEMU layer.  Indeed, going forward, I'd like to see all the smbios
> > >>> stuff moved up to QEMU.
> > >>>
> > >>> Is there something in these two patches that can't be done in QEMU?
> > >>
> > >> But anyhow, right now QEMU seems to be making relatively minor tweaks
> > >> to something that's firmly at home in SeaBIOS, which is why I sent my
> > >> patches to the latter...
> > >
> > >Yeah, that's correct. There's really no particular hook in QEMU to do this.
> > 
> > Would it be OK to apply this in SeaBIOS now, so that 1. it can be
> > useful until whenever SMBIOS gets transferred/absorbed into QEMU,
> > and 2. it won't fall through the cracks when that transition happens ?
> 
> Unfortunately, if we change the smbios in SeaBIOS, it will show up on
> all machine types that use the new version of SeaBIOS.  We've had
> issues with this type of change before as various OSes react
> differently to the change.
> 
> Gerd, what's your take on this change?

I think we can do this in qemu, without touching seabios at all.  The
currently used fw_cfg interface allows to pass both individual fields
and complete tables.  In practice the individual fields interface is
used for type0 and type1 table fields.  I think the only way to pass
complete tables is 'qemu -smbios file=<pregenerated-blob-here>'.

If seabios finds a table provided by qemu it used it, otherwise it
(possibly) generates its own.  So we can smoothly switch over to qemu,
table-by-table.  You can have qemu provide type2+type17 tables, and
leave everything else as-is.  And when doing it in qemu it is easy to do
it for new machine types only.

cheers,
  Gerd
Gabriel L. Somlo Feb. 18, 2014, 7:17 p.m. UTC | #3
On Tue, Feb 18, 2014 at 11:21:33AM +0100, Gerd Hoffmann wrote:
> > Unfortunately, if we change the smbios in SeaBIOS, it will show up on
> > all machine types that use the new version of SeaBIOS.  We've had
> > issues with this type of change before as various OSes react
> > differently to the change.
> > 
> > Gerd, what's your take on this change?
> 
> I think we can do this in qemu, without touching seabios at all.  The
> currently used fw_cfg interface allows to pass both individual fields
> and complete tables.  In practice the individual fields interface is
> used for type0 and type1 table fields.  I think the only way to pass
> complete tables is 'qemu -smbios file=<pregenerated-blob-here>'.

Using Fedora 20 live, I collected the SMBIOS table from the guest
using "dmidecode --dump-bin", with the unpatched SeaBIOS
(dmidecode_pc.bin), SeaBIOS with my patch applied (dmidecode_mac.bin),
and again with unpatched SeaBIOS but with "-smbios file=dmidecode_mac.bin"
on the QEMU command line (dmidecode_cmdline.bin).

I then ran "dmidecode --from-dump" on the three binaries I collected,
and here's what I got:

  $ diff dmi_pc.txt dmi_mac.txt 
  2c2
  < Reading SMBIOS/DMI data from file dmidecode_pc.bin.
  ---
  > Reading SMBIOS/DMI data from file dmidecode_mac.bin.
  4c4
  < 10 structures occupying 298 bytes.
  ---
  > 11 structures occupying 326 bytes.
  29a30,43
  > Handle 0x0200, DMI type 2, 15 bytes
  > Base Board Information
  >       Manufacturer: Bochs
  >       Product Name: Not Specified
  >       Version: Not Specified
  >       Serial Number: Not Specified
  >       Asset Tag: Not Specified
  >       Features:
  >               Board is a hosting board
  >       Location In Chassis: Not Specified
  >       Chassis Handle: 0x0300
  >       Type: Motherboard
  >       Contained Object Handles: 0
  > 
  73c87
  < Handle 0x1100, DMI type 17, 21 bytes
  ---
  > Handle 0x1100, DMI type 17, 27 bytes
  85a100,104
  >       Speed: Unknown
  >       Manufacturer: Not Specified
  >       Serial Number: Not Specified
  >       Asset Tag: Not Specified
  >       Part Number: Not Specified

This looks as expected (we have a new Type 2 entry, and the Type 17
entry now has version 2.3 fields where it didn't use to before).

However, when I compare unmodified SMBIOS against what I get when
supplying the patched binary table via command line, I get this:

  $ diff dmi_pc.txt dmi_cmdline.txt 
  2c2
  < Reading SMBIOS/DMI data from file dmidecode_pc.bin.
  ---
  > Reading SMBIOS/DMI data from file dmidecode_cmdline.bin.
  4c4
  < 10 structures occupying 298 bytes.
  ---
  > 11 structures occupying 657 bytes.
  108,109c108,120
  < Handle 0x7F00, DMI type 127, 4 bytes
  < End Of Table
  ---
  > Handle 0x5F4D, DMI type 95, 83 bytes
  > Unknown Type
  >       Header and Data:
  >               5F 53 4D 5F 32 1F 02 04 4B 00 00 00 00 00 00 00
  >               5F 44 4D 49 5F D2 46 01 20 00 00 00 0B 00 24 00
  >               00 18 00 00 01 02 00 E8 03 00 08 00 00 00 00 00
  >               00 00 00 04 01 00 FF FF 42 6F 63 68 73 00 42 6F
  >               63 68 73 00 30 31 2F 30 31 2F 32 30 31 31 00 00
  >               01 1B 00
  >       Strings:
  >               ....
  > 
  > Invalid entry length (0). DMI table is broken! Stop.

No Type 2, no extra fields for Type 17, and a corrupt table to boot.
 
> If seabios finds a table provided by qemu it used it, otherwise it
> (possibly) generates its own.  So we can smoothly switch over to qemu,
> table-by-table.  You can have qemu provide type2+type17 tables, and
> leave everything else as-is.  And when doing it in qemu it is easy to do
> it for new machine types only.

Sending a patch against QEMU would have definitely been my first
choice, by a wide margin :) But after studying the hw/i386/smbios.c
source file in QEMU for a while, I walked away with the impression
that all it really tries to do is edit a few of the Type 0 and Type 1
fields, and that the hand-over logic between QEMU and SeaBIOS is not
ready for prime time yet.

So I sent the patch to SeaBIOS, where it seems to do what I want it to :)

I could try to hack at the QEMU smbios source file to try to find
where the problem lies (at least why handover to SeaBIOS doesn't work
as expected), but I'm not sure providing command line flags for
inputting each record type individually is a scalable way to move
forward.

Perhaps if there were a DMI/SMBIOS compiler (the reverse action of
"dmidecode --from-dump", something that would take a text "source"
table and generate a .bin from it), we could focus on getting the
"-smbios file=<foo>" bit working correctly, and we could provide
instructions in the docs on how users can build their own smbios
tables.

But I couldn't find anything out there that would "compile" a smbios
table from some type of human-readable (ascii) form...

Any thoughts ?

Thanks,
--Gabriel

PS. I tried the patched SeaBIOS (with v2.3 type17 and added type2) on
XP, Windows7, and Linux, and all of them seemed happy and none of them
seemed to mind... Just sayin' ;)
Kevin O'Connor Feb. 18, 2014, 8:02 p.m. UTC | #4
On Tue, Feb 18, 2014 at 02:17:29PM -0500, Gabriel L. Somlo wrote:
> Sending a patch against QEMU would have definitely been my first
> choice, by a wide margin :) But after studying the hw/i386/smbios.c
> source file in QEMU for a while, I walked away with the impression
> that all it really tries to do is edit a few of the Type 0 and Type 1
> fields, and that the hand-over logic between QEMU and SeaBIOS is not
> ready for prime time yet.

The current mechanism for passing smbios from QEMU to SeaBIOS is
horrible.

> So I sent the patch to SeaBIOS, where it seems to do what I want it to :)
> 
> I could try to hack at the QEMU smbios source file to try to find
> where the problem lies (at least why handover to SeaBIOS doesn't work
> as expected), but I'm not sure providing command line flags for
> inputting each record type individually is a scalable way to move
> forward.

In my opinion, generating the entire smbios table in QEMU and using
the "romfile_loader" mechanism (see seabios src/fw/romfile_loader.c)
would be the preferred solution.  I understand that this is more than
you signed up for.

> Perhaps if there were a DMI/SMBIOS compiler (the reverse action of
> "dmidecode --from-dump", something that would take a text "source"
> table and generate a .bin from it), we could focus on getting the
> "-smbios file=<foo>" bit working correctly, and we could provide
> instructions in the docs on how users can build their own smbios
> tables.
> 
> But I couldn't find anything out there that would "compile" a smbios
> table from some type of human-readable (ascii) form...
> 
> Any thoughts ?
> 
> Thanks,
> --Gabriel
> 
> PS. I tried the patched SeaBIOS (with v2.3 type17 and added type2) on
> XP, Windows7, and Linux, and all of them seemed happy and none of them
> seemed to mind... Just sayin' ;)

Thanks for running tests.  One thing that has bitten us in the past is
OSes re-running license checks and/or popping up "new hardware"
notifications on bios table changes.

-Kevin
Laszlo Ersek Feb. 18, 2014, 9:08 p.m. UTC | #5
On 02/18/14 20:17, Gabriel L. Somlo wrote:
> On Tue, Feb 18, 2014 at 11:21:33AM +0100, Gerd Hoffmann wrote:

> Using Fedora 20 live, I collected the SMBIOS table from the guest
> using "dmidecode --dump-bin", with the unpatched SeaBIOS
> (dmidecode_pc.bin), SeaBIOS with my patch applied (dmidecode_mac.bin),
> and again with unpatched SeaBIOS but with "-smbios file=dmidecode_mac.bin"
> on the QEMU command line (dmidecode_cmdline.bin).

[...]

> However, when I compare unmodified SMBIOS against what I get when
> supplying the patched binary table via command line, I get this:
> 
>   $ diff dmi_pc.txt dmi_cmdline.txt 
>   2c2
>   < Reading SMBIOS/DMI data from file dmidecode_pc.bin.
>   ---
>   > Reading SMBIOS/DMI data from file dmidecode_cmdline.bin.
>   4c4
>   < 10 structures occupying 298 bytes.
>   ---
>   > 11 structures occupying 657 bytes.
>   108,109c108,120
>   < Handle 0x7F00, DMI type 127, 4 bytes
>   < End Of Table
>   ---
>   > Handle 0x5F4D, DMI type 95, 83 bytes
>   > Unknown Type
>   >       Header and Data:
>   >               5F 53 4D 5F 32 1F 02 04 4B 00 00 00 00 00 00 00
>   >               5F 44 4D 49 5F D2 46 01 20 00 00 00 0B 00 24 00
>   >               00 18 00 00 01 02 00 E8 03 00 08 00 00 00 00 00
>   >               00 00 00 04 01 00 FF FF 42 6F 63 68 73 00 42 6F
>   >               63 68 73 00 30 31 2F 30 31 2F 32 30 31 31 00 00
>   >               01 1B 00
>   >       Strings:
>   >               ....
>   > 
>   > Invalid entry length (0). DMI table is broken! Stop.
> 
> No Type 2, no extra fields for Type 17, and a corrupt table to boot.

I had tested this qemu interface with my OVMF SMBIOS patches. It works.
(I used a Type 3 table.)

The problem in this case is that you can't just pass in a raw dump from
dmidecode. You need to prefix it with "smbios_header":

struct smbios_table {
    struct smbios_header header;
    uint8_t data[];
} QEMU_PACKED;

struct smbios_header {
    uint16_t length;
    uint8_t type;
} QEMU_PACKED;

You need to set "type" to 1 (SMBIOS_TABLE_ENTRY), and set "length" so
that it covers the entire "smbios_table" struct (ie. both header and
payload, where payload is your SMBIOS table). "length" is little endian.

Laszlo
Laszlo Ersek Feb. 18, 2014, 9:28 p.m. UTC | #6
On 02/18/14 22:08, Laszlo Ersek wrote:
> On 02/18/14 20:17, Gabriel L. Somlo wrote:
>> On Tue, Feb 18, 2014 at 11:21:33AM +0100, Gerd Hoffmann wrote:
> 
>> Using Fedora 20 live, I collected the SMBIOS table from the guest
>> using "dmidecode --dump-bin", with the unpatched SeaBIOS
>> (dmidecode_pc.bin), SeaBIOS with my patch applied (dmidecode_mac.bin),
>> and again with unpatched SeaBIOS but with "-smbios file=dmidecode_mac.bin"
>> on the QEMU command line (dmidecode_cmdline.bin).
> 
> [...]
> 
>> However, when I compare unmodified SMBIOS against what I get when
>> supplying the patched binary table via command line, I get this:
>>
>>   $ diff dmi_pc.txt dmi_cmdline.txt 
>>   2c2
>>   < Reading SMBIOS/DMI data from file dmidecode_pc.bin.
>>   ---
>>   > Reading SMBIOS/DMI data from file dmidecode_cmdline.bin.
>>   4c4
>>   < 10 structures occupying 298 bytes.
>>   ---
>>   > 11 structures occupying 657 bytes.
>>   108,109c108,120
>>   < Handle 0x7F00, DMI type 127, 4 bytes
>>   < End Of Table
>>   ---
>>   > Handle 0x5F4D, DMI type 95, 83 bytes
>>   > Unknown Type
>>   >       Header and Data:
>>   >               5F 53 4D 5F 32 1F 02 04 4B 00 00 00 00 00 00 00
>>   >               5F 44 4D 49 5F D2 46 01 20 00 00 00 0B 00 24 00
>>   >               00 18 00 00 01 02 00 E8 03 00 08 00 00 00 00 00
>>   >               00 00 00 04 01 00 FF FF 42 6F 63 68 73 00 42 6F
>>   >               63 68 73 00 30 31 2F 30 31 2F 32 30 31 31 00 00
>>   >               01 1B 00
>>   >       Strings:
>>   >               ....
>>   > 
>>   > Invalid entry length (0). DMI table is broken! Stop.
>>
>> No Type 2, no extra fields for Type 17, and a corrupt table to boot.
> 
> I had tested this qemu interface with my OVMF SMBIOS patches. It works.
> (I used a Type 3 table.)
> 
> The problem in this case is that you can't just pass in a raw dump from
> dmidecode. You need to prefix it with "smbios_header":
> 
> struct smbios_table {
>     struct smbios_header header;
>     uint8_t data[];
> } QEMU_PACKED;
> 
> struct smbios_header {
>     uint16_t length;
>     uint8_t type;
> } QEMU_PACKED;
> 
> You need to set "type" to 1 (SMBIOS_TABLE_ENTRY), and set "length" so
> that it covers the entire "smbios_table" struct (ie. both header and
> payload, where payload is your SMBIOS table). "length" is little endian.

Oh wait, scratch that, qemu should do this for you.

But, I retested the thing (with my original Type 3 file), and it still
seems to work.

-smbios file=/home/virt-images/smbios/type3

000000 03 14 00 03 01 01 00 00 00 03 03 03 02 00 00 00
000010 00 00 00 00 52 65 64 20 48 61 74 00 00

Dumped in the OVMF guest:

Handle 0x0000, DMI type 3, 20 bytes
Chassis Information
        Manufacturer: Red Hat
        Type: Other
        Lock: Not Present
        Version: Not Specified
        Serial Number: Not Specified
        Asset Tag: Not Specified
        Boot-up State: Safe
        Power Supply State: Safe
        Thermal State: Safe
        Security Status: Unknown
        OEM Information: 0x00000000
        Height: Unspecified
        Number Of Power Cords: Unspecified

What was the exact command line you used?

... Ah, I think I understand. When you issued dmidecode --dump-bin, that
dumped *all* of the tables. (--dump-bin is mutually exclusive with
--type.) You can't pass multiple tables with one '-smbios file=XXX qemu
option. You need separate binary dumps (one per table), and should pass
them with one -smbios file=XXX option each.

Thanks
Laszlo
Gerd Hoffmann Feb. 19, 2014, 9:46 a.m. UTC | #7
Hi,

> In my opinion, generating the entire smbios table in QEMU and using
> the "romfile_loader" mechanism (see seabios src/fw/romfile_loader.c)
> would be the preferred solution.  I understand that this is more than
> you signed up for.

Yes, this is where we should end up long-term.  For the time being I
think it is fine to use the existing mechanism to switch over table by
table, and once we have the code to generate all tables in qemu we can
switch over to an interface where we simply pass all tables as single
blob.  I think we don't even need the romfile_loader, or do have smbios
tables pointers which need to be fixed up?

cheers,
  Gerd
Gerd Hoffmann Feb. 19, 2014, 9:59 a.m. UTC | #8
Hi,

> However, when I compare unmodified SMBIOS against what I get when
> supplying the patched binary table via command line, I get this:

As Laszlo already sayed: one table per file.
 
> > If seabios finds a table provided by qemu it used it, otherwise it
> > (possibly) generates its own.  So we can smoothly switch over to qemu,
> > table-by-table.  You can have qemu provide type2+type17 tables, and
> > leave everything else as-is.  And when doing it in qemu it is easy to do
> > it for new machine types only.
> 
> I could try to hack at the QEMU smbios source file to try to find
> where the problem lies (at least why handover to SeaBIOS doesn't work
> as expected), but I'm not sure providing command line flags for
> inputting each record type individually is a scalable way to move
> forward.

Agree.  qemu should simply autogenerate the entries (where it can).
i.e. basically port seabios smbios_init_type_17 function to qemu, then
hook the result into the smbios_entries array.  The code to do that is
in smbios_entry_add().  You probably want to factor that out ino a small
helper function which is then called by both smbios_entry_add() and the
type17 init function.

cheers,
  Gerd
diff mbox

Patch

diff --git a/src/fw/smbios.c b/src/fw/smbios.c
index 55c662a..5b76468 100644
--- a/src/fw/smbios.c
+++ b/src/fw/smbios.c
@@ -251,6 +251,41 @@  smbios_init_type_1(void *start)
     return end;
 }
 
+/* Type 2 -- Base Board */
+static void *
+smbios_init_type_2(void *start)
+{
+    struct smbios_type_2 *p = (struct smbios_type_2 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_2);
+    size_t size;
+    int str_index = 0;
+
+    p->header.type = 2;
+    p->header.length = sizeof(struct smbios_type_2);
+    p->header.handle = 0x200;
+
+    load_str_field_with_default(2, manufacturer_str, BUILD_APPNAME);
+    load_str_field_or_skip(2, product_str);
+    load_str_field_or_skip(2, version_str);
+    load_str_field_or_skip(2, serial_number_str);
+    load_str_field_or_skip(2, asset_tag_number_str);
+    load_str_field_or_skip(2, location_str);
+
+    set_field_with_default(2, feature_flags, 0x01); /* Motherboard */
+    set_field_with_default(2, chassis_handle, 0x300); /* T3 System Enclosure */
+    set_field_with_default(2, board_type, 0x0a); /* Motherboard */
+    set_field_with_default(2, contained_element_count, 0);
+
+    *end = 0;
+    end++;
+    if (!str_index) {
+        *end = 0;
+        end++;
+    }
+
+    return end;
+}
+
 /* Type 3 -- System Enclosure */
 static void *
 smbios_init_type_3(void *start)
@@ -417,6 +452,12 @@  smbios_init_type_17(void *start, u32 size_mb, int instance)
     set_field_with_default(17, memory_type, 0x07); /* RAM */
     set_field_with_default(17, type_detail, 0);
 
+    set_field_with_default(17, speed, 0); /* unknown */
+    load_str_field_or_skip(17, manufacturer_str);
+    load_str_field_or_skip(17, serial_number_str);
+    load_str_field_or_skip(17, asset_tag_number_str);
+    load_str_field_or_skip(17, part_number_str);
+
     *end = 0;
     end++;
     if (!str_index) {
@@ -540,6 +581,7 @@  smbios_setup(void)
 
     add_struct(0, p);
     add_struct(1, p);
+    add_struct(2, p);
     add_struct(3, p);
 
     int cpu_num;
diff --git a/src/std/smbios.h b/src/std/smbios.h
index 0513716..86a4c57 100644
--- a/src/std/smbios.h
+++ b/src/std/smbios.h
@@ -59,6 +59,22 @@  struct smbios_type_1 {
     u8 family_str;
 } PACKED;
 
+/* SMBIOS type 2 - Base Board */
+struct smbios_type_2 {
+    struct smbios_structure_header header;
+    u8 manufacturer_str;
+    u8 product_str;
+    u8 version_str;
+    u8 serial_number_str;
+    u8 asset_tag_number_str;
+    u8 feature_flags;
+    u8 location_str;
+    u16 chassis_handle;
+    u8 board_type;
+    u8 contained_element_count;
+    // contained elements follow
+} PACKED;
+
 /* SMBIOS type 3 - System Enclosure (v2.3) */
 struct smbios_type_3 {
     struct smbios_structure_header header;
@@ -127,6 +143,12 @@  struct smbios_type_17 {
     u8 bank_locator_str;
     u8 memory_type;
     u16 type_detail;
+    /* v2.3 fields: */
+    u16 speed;
+    u8 manufacturer_str;
+    u8 serial_number_str;
+    u8 asset_tag_number_str;
+    u8 part_number_str;
 } PACKED;
 
 /* SMBIOS type 19 - Memory Array Mapped Address */