[request-sponsor] 6335559, 6335549, 6335547: fixes for various smbios / prtdiag issues

2005-10-17 Thread Michael Shapiro

 6335559: smbios utility reports bogus cache size information
 6335549: prtdiag: can't get smbios tables on toshiba tecra s1 laptop
 6335547: smbios intermediate checksum computation is broken, rejects valid 
 smbios tables

 See each bug's work around section for a suggested fix, with the exception of
 CR 6335547 (see the attachment for a new suggested fix for 6335547).

Thanks for the suggested fixes and bug reports.  I'm already working on a wad
of changes that addresses these and expect to have it integrated shortly,
so we're all set for the moment.

-Mike

-- 
Mike Shapiro, Solaris Kernel Development. blogs.sun.com/mws/



[request-sponsor] 6335559, 6335549, 6335547: fixes for various smbios / prtdiag issues

2005-10-12 Thread Jürgen Keil
6335559: smbios utility reports bogus cache size information
6335549: prtdiag: can't get smbios tables on toshiba tecra s1 laptop
6335547: smbios intermediate checksum computation is broken, rejects valid 
smbios tables

See each bug's work around section for a suggested fix, with the exception of
CR 6335547 (see the attachment for a new suggested fix for 6335547).
This message posted from opensolaris.org
-- next part --
Diskless snv_22 client, ASUS A7V mainboard, bfu'ed to snv_23:

% prtdiag
prtdiag: failed to open SMBIOS: System does not export an SMBIOS table

/var/adm/messages:

Oct  8 20:05:17 moritz unix: [ID 672469 kern.info] SMBIOS not loaded (SMBIOS 
header checksum mismatch)



open /dev/smbios fails with ENXIO, because in the kernel, ksmbios == NULL.

This happens in post_startup():

ksmbios = smbios_open(NULL, SMB_VERSION, ksmbios_flags, NULL);


Root cause:

usr/src/common/smbios/smb_open.c function smbios_bufopen() computes an 
'isum' checksum like this:

76  smbios_hdl_t *
77  smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len,
78  int version, int flags, int *errp)
79  {
   ...
   132  for (p = (uchar_t *)ep-smbe_ianchor; p  q + sizeof 
(*ep); p++)
   133  isum += *p;

The computed 'isum' checksum has a value != 0.

Problem is that the smbios entry structure has an odd length of 31 bytes, 
but the smbios_entry_t type definition is not 'packed' so that the compiler
works with an extra filler byte at the end and a sizeof(*ep) of 32 bytes.
One extra byte is included in the comupted checksum, the computed checksum
is bogus.

The smbios bios reference specification defines the intermediate checksum
as the sum of the values starting at offset 10h for 0Fh bytes (Solaris
sums 10h bytes).



XXX Old suggested fix:
XXX 
XXX In usr/src/uts/common/sys/smbios.h, use #pragma pack(1) around the
XXX smbios_entry_t typedef.
XXX
XXX but this breaks smbios on a Peacock Freeliner XP10 AMD laptop.

New suggested fix:

Don't rely on sizeof(smbios_entry_t) when computing/verifying the smbe_icksum.
Use the range of bytes [smbe_ianchor .. smbe_bcdrev] to compute/verify the
checksum.

*** usr/src/common/smbios/smb_open.c~   2005-10-10 19:14:20.155332000 +0200
--- usr/src/common/smbios/smb_open.c2005-10-11 17:15:12.305958000 +0200
***
*** 129,135 
for (p = q; p  q + ep-smbe_elen; p++)
esum += *p;
  
!   for (p = (uchar_t *)ep-smbe_ianchor; p  q + sizeof (*ep); p++)
isum += *p;
  
if (esum != 0 || isum != 0) {
--- 129,137 
for (p = q; p  q + ep-smbe_elen; p++)
esum += *p;
  
!   for (p = (uchar_t *)ep-smbe_ianchor;
!p = (uchar_t *)ep-smbe_bcdrev;
!p++)
isum += *p;
  
if (esum != 0 || isum != 0) {
***
*** 265,271 
  
ep-smbe_ecksum = ep-smbe_icksum = 0;
  
!   for (p = (uchar_t *)ep-smbe_ianchor; p  q + sizeof (*ep); p++)
isum += *p;
  
ep-smbe_icksum = -isum;
--- 267,275 
  
ep-smbe_ecksum = ep-smbe_icksum = 0;
  
!   for (p = (uchar_t *)ep-smbe_ianchor;
!p = (uchar_t *)ep-smbe_bcdrev;
!p++)
isum += *p;
  
ep-smbe_icksum = -isum;