Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com ---
src/smbios.c | 68 +++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/src/smbios.c b/src/smbios.c index f948d78..7bcdcb3 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -246,7 +246,9 @@ smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs) p->location = 0x01; /* other */ p->use = 0x03; /* system memory */ p->error_correction = 0x06; /* Multi-bit ECC to make Microsoft happy */ - p->maximum_capacity = memory_size_mb * 1024; + /* 0x80000000 = unknown, accept sizes < 2TB - TODO multiple arrays */ + p->maximum_capacity = memory_size_mb < 2 << 20 ? + memory_size_mb << 10 : 0x80000000; p->memory_error_information_handle = 0xfffe; /* none provided */ p->number_of_memory_devices = nr_mem_devs;
@@ -258,7 +260,7 @@ smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs)
/* Type 17 -- Memory Device */ static void * -smbios_init_type_17(void *start, u32 memory_size_mb, int instance) +smbios_init_type_17(void *start, u32 size_mb, int instance) { struct smbios_type_17 *p = (struct smbios_type_17 *)start;
@@ -270,7 +272,7 @@ smbios_init_type_17(void *start, u32 memory_size_mb, int instance) p->total_width = 64; p->data_width = 64; /* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */ - p->size = memory_size_mb; + p->size = size_mb; p->form_factor = 0x09; /* DIMM */ p->device_set = 0; p->device_locator_str = 1; @@ -289,7 +291,7 @@ smbios_init_type_17(void *start, u32 memory_size_mb, int instance)
/* Type 19 -- Memory Array Mapped Address */ static void * -smbios_init_type_19(void *start, u32 memory_size_mb, int instance) +smbios_init_type_19(void *start, u32 start_mb, u32 size_mb, int instance) { struct smbios_type_19 *p = (struct smbios_type_19 *)start;
@@ -297,8 +299,8 @@ smbios_init_type_19(void *start, u32 memory_size_mb, int instance) p->header.length = sizeof(struct smbios_type_19); p->header.handle = 0x1300 + instance;
- p->starting_address = instance << 24; - p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; + p->starting_address = start_mb << 10; + p->ending_address = p->starting_address + (size_mb << 10) - 1; p->memory_array_handle = 0x1000; p->partition_width = 1;
@@ -310,7 +312,8 @@ smbios_init_type_19(void *start, u32 memory_size_mb, int instance)
/* Type 20 -- Memory Device Mapped Address */ static void * -smbios_init_type_20(void *start, u32 memory_size_mb, int instance) +smbios_init_type_20(void *start, u32 start_mb, u32 size_mb, int instance, + int dev_handle, int array_handle) { struct smbios_type_20 *p = (struct smbios_type_20 *)start;
@@ -318,10 +321,10 @@ smbios_init_type_20(void *start, u32 memory_size_mb, int instance) p->header.length = sizeof(struct smbios_type_20); p->header.handle = 0x1400 + instance;
- p->starting_address = instance << 24; - p->ending_address = p->starting_address + (memory_size_mb << 10) - 1; - p->memory_device_handle = 0x1100 + instance; - p->memory_array_mapped_address_handle = 0x1300 + instance; + p->starting_address = start_mb << 10; + p->ending_address = p->starting_address + (size_mb << 10) - 1; + p->memory_device_handle = 0x1100 + dev_handle; + p->memory_array_mapped_address_handle = 0x1300 + array_handle; p->partition_row_position = 1; p->interleave_position = 0; p->interleaved_data_depth = 0; @@ -405,21 +408,36 @@ smbios_init(void) int cpu_num; for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++) add_struct(4, p, cpu_num); - u64 memsize = RamSizeOver4G; - if (memsize) - memsize += 0x100000000ull; - else - memsize = RamSize; - memsize = memsize / (1024 * 1024); - int nr_mem_devs = (memsize + 0x3fff) >> 14; - add_struct(16, p, memsize, nr_mem_devs); - int i; + + int ram_mb = (RamSize + RamSizeOver4G) >> 20; + int nr_mem_devs = (ram_mb + 0x3fff) >> 14; + add_struct(16, p, ram_mb, nr_mem_devs); + + int i, j; for (i = 0; i < nr_mem_devs; i++) { - u32 dev_memsize = ((i == (nr_mem_devs - 1)) - ? (((memsize-1) & 0x3fff)+1) : 0x4000); - add_struct(17, p, dev_memsize, i); - add_struct(19, p, dev_memsize, i); - add_struct(20, p, dev_memsize, i); + u32 dev_mb = ((i == (nr_mem_devs - 1)) + ? (((ram_mb - 1) & 0x3fff) + 1) + : 16384); + add_struct(17, p, dev_mb, i); + } + + add_struct(19, p, 0, RamSize >> 20, 0); + if (RamSizeOver4G) + add_struct(19, p, 4096, RamSizeOver4G >> 20, 1); + + add_struct(20, p, 0, RamSize >> 20, 0, 0, 0); + if (RamSizeOver4G) { + u32 start_mb = 4096; + for (j = 1, i = 0; i < nr_mem_devs; i++, j++) { + u32 dev_mb = ((i == (nr_mem_devs - 1)) + ? (((ram_mb - 1) & 0x3fff) + 1) + : 16384); + if (i == 0) + dev_mb -= RamSize >> 20; + + add_struct(20, p, start_mb, dev_mb, j, i, 1); + start_mb += dev_mb; + } }
add_struct(32, p);
Alex Williamson wrote:
Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com
Tested on rhel5 guest assigned a variety of mem sizes (3.2, 3.4, 3.5, 3.7, 3.9, 4.0, 4.1, 4.2, 17G); crossed 16G boundary due to limit of descriptor to this size to ensure that was working as well.
Acked-by: Donald Dutile ddutile@redhat.com
On Fri, May 07, 2010 at 01:38:55PM -0600, Alex Williamson wrote:
Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com
Looks okay to me. If there are no other comments, I'll commit in the next couple of days.
-Kevin
On Sun, May 09, 2010 at 11:03:37PM -0400, Kevin O'Connor wrote:
On Fri, May 07, 2010 at 01:38:55PM -0600, Alex Williamson wrote:
Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com
Looks okay to me. If there are no other comments, I'll commit in the next couple of days.
Looks fine to me.
-- Gleb.
Kevin O'Connor wrote:
On Fri, May 07, 2010 at 01:38:55PM -0600, Alex Williamson wrote:
Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com
Looks okay to me. If there are no other comments, I'll commit in the next couple of days.
-Kevin
If i don't mistake it seems to address what i have reported back in January in the "wrong memsize in smbios_init()" thread [1], correct?
[1] http://www.seabios.org/pipermail/seabios/2010-January/000146.html
Sebastian
On Mon, 2010-05-10 at 23:05 +0200, Sebastian Herbszt wrote:
Kevin O'Connor wrote:
On Fri, May 07, 2010 at 01:38:55PM -0600, Alex Williamson wrote:
Avoid counting the io hole as part of ram, a vm started with 4G should report 4G in smbios, not 4.5G.
Signed-off-by: Alex Williamson alex.williamson@redhat.com
Looks okay to me. If there are no other comments, I'll commit in the next couple of days.
-Kevin
If i don't mistake it seems to address what i have reported back in January in the "wrong memsize in smbios_init()" thread [1], correct?
[1] http://www.seabios.org/pipermail/seabios/2010-January/000146.html
Yes, it should fix that. I started out effectively where you did, changing memsize to RamSize + RamSizeOver4G, but then quickly ran into the problems Gleb pointed out with some tables wanting address ranges and others wanting quantity. With this patch tables 16, 17, 19, and 20 should make sense and match the spec. Thanks,
Alex