From: Gleb Natapov <gleb@redhat.com>
To: kevin@koconnor.net
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 1/2] resolve memory device roll over reporting issues with >32G guests
Date: Wed, 7 Oct 2009 18:16:50 +0200 [thread overview]
Message-ID: <1254932211-28010-1-git-send-email-gleb@redhat.com> (raw)
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
This is port of commit e65bb0d2bd3a156408996674965555979de3a61b
from qemu pc-bios tree.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
src/smbios.c | 70 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/smbios.c b/src/smbios.c
index c408601..30dc853 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -366,7 +366,7 @@ smbios_type_4_init(void *start, unsigned int cpu_number)
/* Type 16 -- Physical Memory Array */
static void *
-smbios_type_16_init(void *start)
+smbios_type_16_init(void *start, u32 memory_size_mb, int nr_mem_devs)
{
struct smbios_type_16 *p = (struct smbios_type_16*)start;
@@ -377,10 +377,9 @@ smbios_type_16_init(void *start)
p->location = 0x01; /* other */
p->use = 0x03; /* system memory */
p->error_correction = 0x01; /* other */
- u64 memsize = RamSize + RamSizeOver4G;
- p->maximum_capacity = memsize / 1024;
+ p->maximum_capacity = memory_size_mb * 1024;
p->memory_error_information_handle = 0xfffe; /* none provided */
- p->number_of_memory_devices = 1;
+ p->number_of_memory_devices = nr_mem_devs;
start += sizeof(struct smbios_type_16);
*((u16 *)start) = 0;
@@ -390,21 +389,19 @@ smbios_type_16_init(void *start)
/* Type 17 -- Memory Device */
static void *
-smbios_type_17_init(void *start)
+smbios_type_17_init(void *start, u32 memory_size_mb, int instance)
{
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
p->header.type = 17;
p->header.length = sizeof(struct smbios_type_17);
- p->header.handle = 0x1100;
+ p->header.handle = 0x1100 + instance;
p->physical_memory_array_handle = 0x1000;
p->total_width = 64;
p->data_width = 64;
- /* truncate memory_size_mb to 16 bits and clear most significant
- bit [indicates size in MB] */
- u64 memsize = RamSize + RamSizeOver4G;
- p->size = (u16) (memsize / (1024*1024)) & 0x7fff;
+/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */
+ p->size = memory_size_mb;
p->form_factor = 0x09; /* DIMM */
p->device_set = 0;
p->device_locator_str = 1;
@@ -413,7 +410,8 @@ smbios_type_17_init(void *start)
p->type_detail = 0;
start += sizeof(struct smbios_type_17);
- memcpy((char *)start, "DIMM 1", 7);
+ memcpy((char *)start, "DIMM 0", 7);
+ ((char*)start)[5] += instance;
start += 7;
*((u8 *)start) = 0;
@@ -422,21 +420,16 @@ smbios_type_17_init(void *start)
/* Type 19 -- Memory Array Mapped Address */
static void *
-smbios_type_19_init(void *start)
+smbios_type_19_init(void *start, u32 memory_size_mb, int instance)
{
struct smbios_type_19 *p = (struct smbios_type_19 *)start;
p->header.type = 19;
p->header.length = sizeof(struct smbios_type_19);
- p->header.handle = 0x1300;
+ p->header.handle = 0x1300 + instance;
- p->starting_address = 0;
- u64 memsize = RamSizeOver4G;
- if (memsize)
- memsize += 0x100000000ull;
- else
- memsize = RamSize;
- p->ending_address = memsize / 1024 - 1;
+ p->starting_address = instance << 24;
+ p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
p->memory_array_handle = 0x1000;
p->partition_width = 1;
@@ -448,23 +441,18 @@ smbios_type_19_init(void *start)
/* Type 20 -- Memory Device Mapped Address */
static void *
-smbios_type_20_init(void *start)
+smbios_type_20_init(void *start, u32 memory_size_mb, int instance)
{
struct smbios_type_20 *p = (struct smbios_type_20 *)start;
p->header.type = 20;
p->header.length = sizeof(struct smbios_type_20);
- p->header.handle = 0x1400;
+ p->header.handle = 0x1400 + instance;
- p->starting_address = 0;
- u64 memsize = RamSizeOver4G;
- if (memsize)
- memsize += 0x100000000ull;
- else
- memsize = RamSize;
- p->ending_address = memsize / 1024 - 1;
- p->memory_device_handle = 0x1100;
- p->memory_array_mapped_address_handle = 0x1300;
+ 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->partition_row_position = 1;
p->interleave_position = 0;
p->interleaved_data_depth = 0;
@@ -540,10 +528,22 @@ smbios_init(void)
int cpu_num, smp_cpus = CountCPUs;
for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
add_struct(smbios_type_4_init(p, cpu_num));
- add_struct(smbios_type_16_init(p));
- add_struct(smbios_type_17_init(p));
- add_struct(smbios_type_19_init(p));
- add_struct(smbios_type_20_init(p));
+ u64 memsize = RamSizeOver4G;
+ if (memsize)
+ memsize += 0x100000000ull;
+ else
+ memsize = RamSize;
+ memsize = memsize / (1024 * 1024);
+ int nr_mem_devs = (memsize + 0x3fff) >> 14;
+ add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
+ int i;
+ for (i = 0; i < nr_mem_devs; i++) {
+ u32 dev_memsize = ((i == (nr_mem_devs - 1))
+ ? (((memsize-1) & 0x3fff)+1) : 0x4000);
+ add_struct(smbios_type_17_init(p, dev_memsize, i));
+ add_struct(smbios_type_19_init(p, dev_memsize, i));
+ add_struct(smbios_type_20_init(p, dev_memsize, i));
+ }
add_struct(smbios_type_32_init(p));
add_struct(smbios_type_127_init(p));
--
1.6.3.3
next reply other threads:[~2009-10-07 16:17 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-07 16:16 Gleb Natapov [this message]
2009-10-07 16:16 ` [Qemu-devel] [PATCH 2/2] Load SMBIOS entries and files from qemu Gleb Natapov
2009-10-07 23:53 ` [Qemu-devel] " Kevin O'Connor
2009-10-08 6:22 ` Gleb Natapov
2009-10-07 23:49 ` [Qemu-devel] Re: [PATCH 1/2] resolve memory device roll over reporting issues with >32G guests Kevin O'Connor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1254932211-28010-1-git-send-email-gleb@redhat.com \
--to=gleb@redhat.com \
--cc=kevin@koconnor.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).