rpms/xen/devel xen-smbios-table-fix.patch, NONE, 1.1 xen.spec, 1.154, 1.155

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Oct 4 21:15:28 UTC 2006


Author: sct

Update of /cvs/dist/rpms/xen/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv24430

Modified Files:
	xen.spec 
Added Files:
	xen-smbios-table-fix.patch 
Log Message:
Fix SMBIOS tables for SVM guests [danpb] (bug 207501)

xen-smbios-table-fix.patch:
 tools/firmware/hvmloader/hvmloader.c                             |    6 
 tools/firmware/hvmloader/smbios.c                                |  146 +++-------
 xen-3.0.3-testing-11633.smbios/tools/firmware/hvmloader/smbios.c |    2 
 3 files changed, 56 insertions(+), 98 deletions(-)

--- NEW FILE xen-smbios-table-fix.patch ---
# HG changeset patch
# User kfraser at localhost.localdomain
# Date 1159808696 -3600
# 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 at xensource.com>

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;
diff -ru xen-3.0.3-testing-11633.smbios-orig/tools/firmware/hvmloader/smbios.c xen-3.0.3-testing-11633.smbios/tools/firmware/hvmloader/smbios.c
--- xen-3.0.3-testing-11633.smbios-orig/tools/firmware/hvmloader/smbios.c	2006-10-03 16:02:57.000000000 -0400
+++ xen-3.0.3-testing-11633.smbios/tools/firmware/hvmloader/smbios.c	2006-10-03 16:01:17.000000000 -0400
@@ -434,7 +434,7 @@
 	start += strlen(buf) + 1;
 
 	strcpy((char *)start, cpu_manufacturer);
-	start += strlen(buf) + 1;
+	start += strlen(cpu_manufacturer) + 1;
 
 	*((uint8_t *)start) = 0;
 	return start+1;


Index: xen.spec
===================================================================
RCS file: /cvs/dist/rpms/xen/devel/xen.spec,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -r1.154 -r1.155
--- xen.spec	29 Sep 2006 21:20:26 -0000	1.154
+++ xen.spec	4 Oct 2006 21:15:25 -0000	1.155
@@ -5,7 +5,7 @@
 Summary: Xen is a virtual machine monitor
 Name:    xen
 Version: 3.0.2
-Release: 42
+Release: 43
 Group:   Development/Libraries
 License: GPL
 URL:     http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html
@@ -14,6 +14,7 @@
 Patch1: xen-initscript.patch
 Patch2: xen-nostrip-ioemu.patch
 Patch3: xen-compile-fixes.patch
+Patch4: xen-smbios-table-fix.patch
 Patch6: xen-network-iptables-bridge.patch
 Patch8: xen-vmxballoon-hack.patch
 Patch20: xen-blktap-no-aio-epoll.patch
@@ -99,6 +100,7 @@
 # Don't strip qemu-dm early, so that we get proper debuginfo
 %patch2 -p1
 %patch3 -p1 -b .compile
+%patch4 -p1
 %patch6 -p1
 #patch8 -p1 # FIXME: need to pull this one back
 
@@ -233,6 +235,9 @@
 %{_libdir}/*.a
 
 %changelog
+* Wed Oct  4 2006 Stephen C. Tweedie <sct at redhat.com> - 3.0.2-43
+- Fix SMBIOS tables for SVM guests [danpb] (bug 207501)
+
 * Fri Sep 29 2006 Daniel P. Berrange <berrange at redhat.com> - 3.0.2-42
 - Added vnclisten patches to make VNC only listen on localhost
   out of the box, configurable by 'vnclisten' parameter (bz 203196)




More information about the fedora-cvs-commits mailing list