From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Bill Rieske" Subject: [PATCH] bios: resolve memory device roll over reporting issues with >32G guests Date: Fri, 07 Nov 2008 14:55:07 -0700 Message-ID: <491456C7.860B.008B.3@novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartA78FF72B.0__=" To: Return-path: Received: from lucius.provo.novell.com ([137.65.248.127]:21012 "EHLO lucius.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751651AbYKGWPN (ORCPT ); Fri, 7 Nov 2008 17:15:13 -0500 Sender: kvm-owner@vger.kernel.org List-ID: This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartA78FF72B.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline The field within the Memory Device type 17 is only a word with the MSB = being used to report MB/KB. Thereby, a guest with 32G and greater would = report incorrect memory device information rolling over to 0. This presents more than one memory device and associated memory structures = if the memory is larger than 16G Signed-off-by: Bill Rieske --=__PartA78FF72B.0__= Content-Type: text/plain; name="smbios-large-mem.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="smbios-large-mem.diff" diff --git a/bios/rombios32.c b/bios/rombios32.c=0Aindex a91b155..bc69945 = 100755=0A--- a/bios/rombios32.c=0A+++ b/bios/rombios32.c=0A@@ -173,6 = +173,26 @@ static inline int isdigit(int c)=0A return c >=3D '0' && c = <=3D '9';=0A }=0A =0A+char *itoa(char *a, unsigned int i)=0A+{=0A+ = unsigned int _i =3D i, x =3D 0;=0A+=0A+ do {=0A+ x++;=0A+ = _i /=3D 10;=0A+ } while ( _i !=3D 0 );=0A+=0A+ a +=3D x;=0A+ *a-- = =3D '\0';=0A+=0A+ do {=0A+ *a-- =3D (i % 10) + '0';=0A+ i = /=3D 10;=0A+ } while ( i !=3D 0 );=0A+=0A+ return a + 1;=0A+}=0A+=0A = void *memset(void *d1, int val, size_t len)=0A {=0A uint8_t *d =3D = d1;=0A@@ -220,6 +240,16 @@ size_t strlen(const char *s)=0A return s1 - = s;=0A }=0A =0A+char *=0A+strcpy(char *dest, const char *src)=0A+{=0A+ = char *p =3D dest;=0A+ while ( *src )=0A+ *p++ =3D *src++;=0A+ = *p =3D 0;=0A+ return dest;=0A+}=0A+=0A /* from BSD ppp sources */=0A = int vsnprintf(char *buf, int buflen, const char *fmt, va_list args)=0A = {=0A@@ -1914,7 +1944,7 @@ smbios_type_4_init(void *start, unsigned int = cpu_number)=0A =0A /* Type 16 -- Physical Memory Array */=0A static void = *=0A-smbios_type_16_init(void *start, uint32_t memsize)=0A+smbios_type_16_i= nit(void *start, uint32_t memsize, int nr_mem_devs)=0A {=0A struct = smbios_type_16 *p =3D (struct smbios_type_16*)start;=0A =0A@@ -1927,7 = +1957,7 @@ smbios_type_16_init(void *start, uint32_t memsize)=0A = p->error_correction =3D 0x01; /* other */=0A p->maximum_capacity =3D = memsize * 1024;=0A p->memory_error_information_handle =3D 0xfffe; /* = none provided */=0A- p->number_of_memory_devices =3D 1;=0A+ = p->number_of_memory_devices =3D nr_mem_devs;=0A =0A start +=3D = sizeof(struct smbios_type_16);=0A *((uint16_t *)start) =3D 0;=0A@@ = -1937,20 +1967,20 @@ smbios_type_16_init(void *start, uint32_t memsize)=0A = =0A /* Type 17 -- Memory Device */=0A static void *=0A-smbios_type_17_init(= void *start, uint32_t memory_size_mb)=0A+smbios_type_17_init(void *start, = uint32_t memory_size_mb, int instance)=0A {=0A+ char buf[16];=0A = struct smbios_type_17 *p =3D (struct smbios_type_17 *)start;=0A =0A = p->header.type =3D 17;=0A p->header.length =3D sizeof(struct smbios_typ= e_17);=0A- p->header.handle =3D 0x1100;=0A+ p->header.handle =3D = 0x1100 + instance;=0A =0A p->physical_memory_array_handle =3D = 0x1000;=0A p->total_width =3D 64;=0A p->data_width =3D 64;=0A- = /* truncate memory_size_mb to 16 bits and clear most significant=0A- = bit [indicates size in MB] */=0A- p->size =3D (uint16_t) memory_size_mb = & 0x7fff;=0A+/* TODO: should assert in case something is wrong ASSERT((me= mory_size_mb & ~0x7fff) =3D=3D 0); */ =0A+ p->size =3D memory_size_mb;= =0A p->form_factor =3D 0x09; /* DIMM */=0A p->device_set =3D 0;=0A = p->device_locator_str =3D 1;=0A@@ -1959,8 +1989,11 @@ smbios_type_17_in= it(void *start, uint32_t memory_size_mb)=0A p->type_detail =3D 0;=0A = =0A start +=3D sizeof(struct smbios_type_17);=0A- memcpy((char = *)start, "DIMM 1", 7);=0A- start +=3D 7;=0A+ memcpy((char *)start, = "DIMM ", 6);=0A+ start +=3D strlen("DIMM ");=0A+ itoa(buf, instance);= =0A+ strcpy(start, buf);=0A+ start +=3D strlen(buf) + 1;=0A = *((uint8_t *)start) =3D 0;=0A =0A return start+1;=0A@@ -1968,16 = +2001,16 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb)=0A = =0A /* Type 19 -- Memory Array Mapped Address */=0A static void *=0A-smbios= _type_19_init(void *start, uint32_t memory_size_mb)=0A+smbios_type_19_init(= void *start, uint32_t memory_size_mb, int instance)=0A {=0A struct = smbios_type_19 *p =3D (struct smbios_type_19 *)start;=0A =0A p->header.= type =3D 19;=0A p->header.length =3D sizeof(struct smbios_type_19);=0A-= p->header.handle =3D 0x1300;=0A+ p->header.handle =3D 0x1300 + = instance;=0A =0A- p->starting_address =3D 0;=0A- p->ending_address = =3D (memory_size_mb * 1024) - 1;=0A+ p->starting_address =3D instance = << 24;=0A+ p->ending_address =3D p->starting_address + (memory_size_mb = << 10) - 1;=0A p->memory_array_handle =3D 0x1000;=0A p->partition_w= idth =3D 1;=0A =0A@@ -1989,18 +2022,18 @@ smbios_type_19_init(void *start, = uint32_t memory_size_mb)=0A =0A /* Type 20 -- Memory Device Mapped Address = */=0A static void *=0A-smbios_type_20_init(void *start, uint32_t memory_siz= e_mb)=0A+smbios_type_20_init(void *start, uint32_t memory_size_mb, int = instance)=0A {=0A struct smbios_type_20 *p =3D (struct smbios_type_20 = *)start;=0A =0A p->header.type =3D 20;=0A p->header.length =3D = sizeof(struct smbios_type_20);=0A- p->header.handle =3D 0x1400;=0A+ = p->header.handle =3D 0x1400 + instance;=0A =0A- p->starting_address =3D = 0;=0A- p->ending_address =3D (memory_size_mb * 1024) - 1;=0A- = p->memory_device_handle =3D 0x1100;=0A- p->memory_array_mapped_address_h= andle =3D 0x1300;=0A+ p->starting_address =3D instance << 24;=0A+ = p->ending_address =3D p->starting_address + (memory_size_mb << 10) - = 1;=0A+ p->memory_device_handle =3D 0x1100 + instance;=0A+ p->memory_a= rray_mapped_address_handle =3D 0x1300 + instance;=0A p->partition_row_p= osition =3D 1;=0A p->interleave_position =3D 0;=0A p->interleaved_d= ata_depth =3D 0;=0A@@ -2051,6 +2084,7 @@ void smbios_init(void)=0A = char *start, *p, *q;=0A int memsize =3D (ram_end =3D=3D ram_size) ? = ram_size / (1024 * 1024) :=0A (ram_end - (1ull << 32) + = ram_size) / (1024 * 1024);=0A+ int i, nr_mem_devs;=0A =0A #ifdef = BX_USE_EBDA_TABLES=0A ebda_cur_addr =3D align(ebda_cur_addr, 16);=0A@@ = -2062,23 +2096,32 @@ void smbios_init(void)=0A =0A p =3D (char = *)start + sizeof(struct smbios_entry_point);=0A =0A-#define add_struct(fn) = { \=0A+#define add_struct(fn) do{ \=0A q =3D (fn); \=0A nr_structs+= +; \=0A if ((q - p) > max_struct_size) \=0A max_struct_size = =3D q - p; \=0A p =3D q; \=0A-}=0A+}while (0)=0A =0A add_struct(smb= ios_type_0_init(p));=0A add_struct(smbios_type_1_init(p));=0A = add_struct(smbios_type_3_init(p));=0A for (cpu_num =3D 1; cpu_num <=3D = smp_cpus; cpu_num++)=0A add_struct(smbios_type_4_init(p, cpu_num));= =0A- add_struct(smbios_type_16_init(p, memsize));=0A- add_struct(smbi= os_type_17_init(p, memsize));=0A- add_struct(smbios_type_19_init(p, = ram_end / (1024 * 1024)));=0A- add_struct(smbios_type_20_init(p, = ram_end / (1024 * 1024)));=0A+=0A+ /* Each 'memory device' covers up to = 16GB of address space. */=0A+ nr_mem_devs =3D (memsize + 0x3fff) >> = 14;=0A+ add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));=0A+ = for ( i =3D 0; i < nr_mem_devs; i++ )=0A+ {=0A+ uint32_t = dev_memsize =3D ((i =3D=3D (nr_mem_devs - 1))=0A+ = ? (memsize & 0x3fff) : 0x4000);=0A+ add_struct(smbios_type_17_= init(p, dev_memsize, i));=0A+ add_struct(smbios_type_19_init(p, = dev_memsize, i));=0A+ add_struct(smbios_type_20_init(p, dev_memsize,= i));=0A+ }=0A+=0A add_struct(smbios_type_32_init(p));=0A = add_struct(smbios_type_127_init(p));=0A =0A --=__PartA78FF72B.0__=--