[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVMLOADER] Clean up SMBIOS table-length computations.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID f426f6e646eb88d143b44f0b60fe1a3f83201509
# Parent  0d796dced5f72023009f9be2612d3f3b6fc095d1
[HVMLOADER] Clean up SMBIOS table-length computations.
It's easier and less prone to error not to attempt the
length computation up front.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/firmware/hvmloader/hvmloader.c |    6 -
 tools/firmware/hvmloader/smbios.c    |  146 ++++++++++++-----------------------
 2 files changed, 55 insertions(+), 97 deletions(-)

diff -r 0d796dced5f7 -r f426f6e646eb tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Mon Oct 02 16:12:41 2006 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Mon Oct 02 18:04:56 2006 +0100
@@ -170,6 +170,9 @@ main(void)
 
        init_hypercalls();
 
+       puts("Writing SMBIOS tables ...\n");
+       hvm_write_smbios_tables();
+
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
 
@@ -201,9 +204,6 @@ main(void)
                }
        }
 
-       puts("Writing SMBIOS tables ...\n");
-       hvm_write_smbios_tables();
-
        if (check_amd()) {
                /* AMD implies this is SVM */
                 puts("SVM go ...\n");
diff -r 0d796dced5f7 -r f426f6e646eb tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Mon Oct 02 16:12:41 2006 +0100
+++ b/tools/firmware/hvmloader/smbios.c Mon Oct 02 18:04:56 2006 +0100
@@ -28,23 +28,15 @@
 #include "util.h"
 #include "hypercall.h"
 
-/* write SMBIOS tables starting at 'start', without writing more
-   than 'max_size' bytes.
-
-   Return the number of bytes written
-*/
 static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
                    uint32_t vcpus, uint64_t memsize,
                    uint8_t uuid[16], char *xen_version,
                    uint32_t xen_major_version, uint32_t xen_minor_version);
 
 static void
 get_cpu_manufacturer(char *buf, int len);
-static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
-                 const char *processor_manufacturer);
-static void *
+static void
 smbios_entry_point_init(void *start,
                        uint16_t max_structure_size,
                        uint16_t structure_table_length,
@@ -71,7 +63,7 @@ smbios_type_20_init(void *start, uint32_
 smbios_type_20_init(void *start, uint32_t memory_size_mb);
 static void *
 smbios_type_32_init(void *start);
-void *
+static void *
 smbios_type_127_init(void *start);
 
 static void
@@ -80,7 +72,8 @@ get_cpu_manufacturer(char *buf, int len)
        char id[12];
        uint32_t eax = 0;
 
-       cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8], (uint32_t 
*)&id[4]);
+       cpuid(0, &eax, (uint32_t *)&id[0], (uint32_t *)&id[8],
+             (uint32_t *)&id[4]);
 
        if (memcmp(id, "GenuineIntel", 12) == 0)
                strncpy(buf, "Intel", len);
@@ -90,90 +83,51 @@ get_cpu_manufacturer(char *buf, int len)
                strncpy(buf, "unknown", len);
 }
 
-
-/* Calculate the size of the SMBIOS structure table.
-*/
 static size_t
-smbios_table_size(uint32_t vcpus, const char *xen_version,
-                 const char *processor_manufacturer)
-{
-       size_t size;
-
-       /* first compute size without strings or terminating 0 bytes */
-       size =  sizeof(struct smbios_type_0) + sizeof(struct smbios_type_1) +
-               sizeof(struct smbios_type_3) + sizeof(struct 
smbios_type_4)*vcpus +
-               sizeof(struct smbios_type_16) + sizeof(struct smbios_type_17) +
-               sizeof(struct smbios_type_19) + sizeof(struct smbios_type_20) +
-               sizeof(struct smbios_type_32) + sizeof(struct smbios_type_127);
-
-       /* 5 structures with no strings, 2 null bytes each */
-       size += 10;
-
-       /* Need to include 1 null byte per structure with strings (first
-          terminating null byte comes from the string terminator of the
-          last string). */
-       size += 4 + vcpus;
-
-       /* type 0: "Xen", xen_version, and release_date */
-       size += strlen("Xen") + strlen(xen_version) + 2;
-       /* type 1: "Xen", xen_version, "HVM domU", UUID as string for 
-                   serial number */
-       size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) +
-                       36 + 4;
-       /* type 3: "Xen" */
-       size += strlen("Xen") + 1;
-       /* type 4: socket designation ("CPU n"), processor_manufacturer */
-       size += vcpus * (strlen("CPU n") + strlen(processor_manufacturer) + 2);
-       /* Make room for two-digit CPU numbers if necessary -- doesn't handle
-          vcpus > 99 */
-       if (vcpus > 9)
-               size += vcpus - 9;
-       /* type 17: device locator string ("DIMM 1") */
-       size += strlen("DIMM 1") + 1;
-
-       return size;
-}
-
-static size_t
-write_smbios_tables(void *start, size_t max_size,
+write_smbios_tables(void *start,
                    uint32_t vcpus, uint64_t memsize,
                    uint8_t uuid[16], char *xen_version,
                    uint32_t xen_major_version, uint32_t xen_minor_version)
 {
-       unsigned cpu_num;
-       void *p = start;
+       unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
+       char *p, *q;
        char cpu_manufacturer[15];
        size_t structure_table_length;
 
        get_cpu_manufacturer(cpu_manufacturer, 15);
 
-
-       structure_table_length = smbios_table_size(vcpus, xen_version,
-                                                  cpu_manufacturer);
-
-       if (structure_table_length + sizeof(struct smbios_entry_point) > 
max_size)
-               return 0;
-
-       p = smbios_entry_point_init(p, sizeof(struct smbios_type_4), 
-                                   structure_table_length,
-                                   (uint32_t)start + 
-                                   sizeof(struct smbios_entry_point),
-                                   9 + vcpus);
-
-       p = smbios_type_0_init(p, xen_version, xen_major_version,
-                              xen_minor_version);
-       p = smbios_type_1_init(p, xen_version, uuid);
-       p = smbios_type_3_init(p);
-       for (cpu_num = 1; cpu_num <= vcpus; ++cpu_num)
-               p = smbios_type_4_init(p, cpu_num, cpu_manufacturer);
-       p = smbios_type_16_init(p, memsize);
-       p = smbios_type_17_init(p, memsize);
-       p = smbios_type_19_init(p, memsize);
-       p = smbios_type_20_init(p, memsize);
-       p = smbios_type_32_init(p);
-       p = smbios_type_127_init(p);
-
-       return (size_t)((char*)p - (char*)start);
+       p = (char *)start + sizeof(struct smbios_entry_point);
+
+#define do_struct(fn) do {                     \
+       q = (fn);                               \
+       nr_structs++;                           \
+       if ((q - p) > max_struct_size)          \
+               max_struct_size = q - p;        \
+       p = q;                                  \
+} while (0)
+
+       do_struct(smbios_type_0_init(p, xen_version, xen_major_version,
+                                    xen_minor_version));
+       do_struct(smbios_type_1_init(p, xen_version, uuid));
+       do_struct(smbios_type_3_init(p));
+       for (cpu_num = 1; cpu_num <= vcpus; cpu_num++)
+               do_struct(smbios_type_4_init(p, cpu_num, cpu_manufacturer));
+       do_struct(smbios_type_16_init(p, memsize));
+       do_struct(smbios_type_17_init(p, memsize));
+       do_struct(smbios_type_19_init(p, memsize));
+       do_struct(smbios_type_20_init(p, memsize));
+       do_struct(smbios_type_32_init(p));
+       do_struct(smbios_type_127_init(p));
+
+#undef do_struct
+
+       smbios_entry_point_init(
+               start, max_struct_size,
+               (p - (char *)start) - sizeof(struct smbios_entry_point),
+               SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point),
+               nr_structs);
+
+       return (size_t)((char *)p - (char *)start);
 }
 
 /* This tries to figure out how much pseudo-physical memory (in MB)
@@ -278,10 +232,16 @@ hvm_write_smbios_tables(void)
 
        xen_version_str[sizeof(xen_version_str)-1] = '\0';
 
-       write_smbios_tables((void *) SMBIOS_PHYSICAL_ADDRESS,
-                           SMBIOS_SIZE_LIMIT, get_vcpu_nr(), get_memsize(),
-                           uuid, xen_version_str,
-                           xen_major_version, xen_minor_version);
+       /* NB. 0xC0000 is a safe large memory area for scratch. */
+       len = write_smbios_tables((void *)0xC0000,
+                                 get_vcpu_nr(), get_memsize(),
+                                 uuid, xen_version_str,
+                                 xen_major_version, xen_minor_version);
+       if (len > SMBIOS_SIZE_LIMIT)
+               goto error_out;
+       /* Okay, not too large: copy out of scratch to final location. */
+       memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len);
+
        return;
 
  error_out:
@@ -290,7 +250,7 @@ hvm_write_smbios_tables(void)
 }
 
 
-static void *
+static void
 smbios_entry_point_init(void *start,
                        uint16_t max_structure_size,
                        uint16_t structure_table_length,
@@ -327,8 +287,6 @@ smbios_entry_point_init(void *start,
        for (i = 0x10; i < ep->length; ++i)
                sum += ((int8_t *)start)[i];
        ep->intermediate_checksum = -sum;
-
-       return (char *)start + sizeof(struct smbios_entry_point);
 }
 
 /* Type 0 -- BIOS Information */
@@ -597,7 +555,7 @@ smbios_type_32_init(void *start)
 }
 
 /* Type 127 -- End of Table */
-void *
+static void *
 smbios_type_127_init(void *start)
 {
        struct smbios_type_127 *p = (struct smbios_type_127 *)start;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.