* [Qemu-devel] [PATCH] Read additional ACPI tables from a VM @ 2009-02-09 14:30 Gleb Natapov 2009-02-09 20:41 ` [Qemu-devel] Re: [Bochs-developers] " Sebastian Herbszt 0 siblings, 1 reply; 8+ messages in thread From: Gleb Natapov @ 2009-02-09 14:30 UTC (permalink / raw) To: qemu-devel; +Cc: bochs-developers diff --git a/bios/rombios32.c b/bios/rombios32.c index f6ce225..29fd40a 100644 --- a/bios/rombios32.c +++ b/bios/rombios32.c @@ -455,6 +455,8 @@ unsigned long bios_table_end_addr; #define QEMU_CFG_SIGNATURE 0x00 #define QEMU_CFG_ID 0x01 #define QEMU_CFG_UUID 0x02 +#define FW_CFG_ARCH_LOCAL 0x8000 +#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) int qemu_cfg_port; @@ -482,6 +484,27 @@ void qemu_cfg_read(uint8_t *buf, int len) while (len--) *(buf++) = inb(QEMU_CFG_DATA_PORT); } + +static int acpi_additional_tables(void) +{ + uint16_t cnt; + + qemu_cfg_select(FW_CFG_ACPI_TABLES); + qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt)); + + return cnt; +} + +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) +{ + qemu_cfg_read((uint8_t*)len, sizeof(*len)); + + if (!*len) + return -1; + + qemu_cfg_read((uint8_t*)addr, *len); + return 0; +} #endif void init_smp_msrs(void) @@ -1545,8 +1568,8 @@ void acpi_bios_init(void) uint32_t hpet_addr; #endif uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr; - uint32_t acpi_tables_size, madt_addr, madt_size; - int i; + uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size; + int i, ext_tbl; /* reserve memory space for tables */ #ifdef BX_USE_EBDA_TABLES @@ -1559,10 +1582,17 @@ void acpi_bios_init(void) bios_table_cur_addr += sizeof(*rsdp); #endif +#ifdef BX_QEMU + ext_tbl = acpi_additional_tables(); +#else + ext_tbl = 0; +#endif + addr = base_addr = ram_size - ACPI_DATA_SIZE; rsdt_addr = addr; rsdt = (void *)(addr); - addr += sizeof(*rsdt); + rsdt_size = sizeof(*rsdt) + ext_tbl * sizeof(rsdt->table_offset_entry[0]); + addr += rsdt_size; fadt_addr = addr; fadt = (void *)(addr); @@ -1601,12 +1631,6 @@ void acpi_bios_init(void) addr += sizeof(*hpet); #endif - acpi_tables_size = addr - base_addr; - - BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", - (unsigned long)rsdp, - (unsigned long)rsdt, acpi_tables_size); - /* RSDP */ memset(rsdp, 0, sizeof(*rsdp)); memcpy(rsdp->signature, "RSD PTR ", 8); @@ -1618,17 +1642,6 @@ void acpi_bios_init(void) rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr); rsdp->checksum = acpi_checksum((void *)rsdp, 20); - /* RSDT */ - memset(rsdt, 0, sizeof(*rsdt)); - rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); - rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); - rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); -#ifdef BX_QEMU - rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); -#endif - acpi_build_table_header((struct acpi_table_header *)rsdt, - "RSDT", sizeof(*rsdt), 1); - /* FADT */ memset(fadt, 0, sizeof(*fadt)); fadt->firmware_ctrl = cpu_to_le32(facs_addr); @@ -1715,6 +1728,37 @@ void acpi_bios_init(void) "HPET", sizeof(*hpet), 1); #endif + +#ifdef BX_QEMU + acpi_additional_tables(); /* resets cfg to required entry */ + for(i = 0; i < ext_tbl; i++) { + uint16_t len; + if(addr >= ram_size) + BX_PANIC("ACPI table overflow\n"); + if(acpi_load_table(i, addr, &len) < 0) + BX_PANIC("Fail to load ACPI table from QEMU\n"); + rsdt->table_offset_entry[i+4] = cpu_to_le32(addr); + addr += len; + } +#endif + + /* RSDT */ + memset(rsdt, 0, sizeof(*rsdt)); + rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); + rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); + rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); +#ifdef BX_QEMU + rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); +#endif + acpi_build_table_header((struct acpi_table_header *)rsdt, + "RSDT", rsdt_size, 1); + + acpi_tables_size = addr - base_addr; + + BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", + (unsigned long)rsdp, + (unsigned long)rsdt, acpi_tables_size); + } /* SMBIOS entry point -- must be written to a 16-bit aligned address -- Gleb. ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM 2009-02-09 14:30 [Qemu-devel] [PATCH] Read additional ACPI tables from a VM Gleb Natapov @ 2009-02-09 20:41 ` Sebastian Herbszt 2009-02-09 21:00 ` Gleb Natapov 0 siblings, 1 reply; 8+ messages in thread From: Sebastian Herbszt @ 2009-02-09 20:41 UTC (permalink / raw) To: Gleb Natapov, qemu-devel; +Cc: bochs-developers Gleb Natapov wrote: Just a quick review. > diff --git a/bios/rombios32.c b/bios/rombios32.c > index f6ce225..29fd40a 100644 > --- a/bios/rombios32.c > +++ b/bios/rombios32.c > @@ -455,6 +455,8 @@ unsigned long bios_table_end_addr; > #define QEMU_CFG_SIGNATURE 0x00 > #define QEMU_CFG_ID 0x01 > #define QEMU_CFG_UUID 0x02 > +#define FW_CFG_ARCH_LOCAL 0x8000 > +#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) No more QEMU_CFG prefix? Or is this different? > int qemu_cfg_port; > > @@ -482,6 +484,27 @@ void qemu_cfg_read(uint8_t *buf, int len) > while (len--) > *(buf++) = inb(QEMU_CFG_DATA_PORT); > } > + > +static int acpi_additional_tables(void) > +{ > + uint16_t cnt; > + > + qemu_cfg_select(FW_CFG_ACPI_TABLES); > + qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt)); > + > + return cnt; > +} > + > +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) > +{ > + qemu_cfg_read((uint8_t*)len, sizeof(*len)); > + > + if (!*len) > + return -1; > + > + qemu_cfg_read((uint8_t*)addr, *len); > + return 0; > +} > #endif > > void init_smp_msrs(void) Can you please diff against bochs cvs? > @@ -1545,8 +1568,8 @@ void acpi_bios_init(void) > uint32_t hpet_addr; > #endif > uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr; > - uint32_t acpi_tables_size, madt_addr, madt_size; > - int i; > + uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size; > + int i, ext_tbl; Might change to uint32_t or uint16_t and ext_tbl to something little more descriptive like external_tables. > > /* reserve memory space for tables */ > #ifdef BX_USE_EBDA_TABLES > @@ -1559,10 +1582,17 @@ void acpi_bios_init(void) > bios_table_cur_addr += sizeof(*rsdp); > #endif > > +#ifdef BX_QEMU > + ext_tbl = acpi_additional_tables(); > +#else > + ext_tbl = 0; > +#endif > + > addr = base_addr = ram_size - ACPI_DATA_SIZE; > rsdt_addr = addr; > rsdt = (void *)(addr); > - addr += sizeof(*rsdt); > + rsdt_size = sizeof(*rsdt) + ext_tbl * sizeof(rsdt->table_offset_entry[0]); Can use 4 instead of the sizeof() since its defined as a 32-bit address. > + addr += rsdt_size; > > fadt_addr = addr; > fadt = (void *)(addr); > @@ -1601,12 +1631,6 @@ void acpi_bios_init(void) > addr += sizeof(*hpet); > #endif > > - acpi_tables_size = addr - base_addr; > - > - BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", > - (unsigned long)rsdp, > - (unsigned long)rsdt, acpi_tables_size); > - > /* RSDP */ > memset(rsdp, 0, sizeof(*rsdp)); > memcpy(rsdp->signature, "RSD PTR ", 8); > @@ -1618,17 +1642,6 @@ void acpi_bios_init(void) > rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr); > rsdp->checksum = acpi_checksum((void *)rsdp, 20); > > - /* RSDT */ > - memset(rsdt, 0, sizeof(*rsdt)); > - rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); > - rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); > - rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); > -#ifdef BX_QEMU > - rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); > -#endif > - acpi_build_table_header((struct acpi_table_header *)rsdt, > - "RSDT", sizeof(*rsdt), 1); > - > /* FADT */ > memset(fadt, 0, sizeof(*fadt)); > fadt->firmware_ctrl = cpu_to_le32(facs_addr); > @@ -1715,6 +1728,37 @@ void acpi_bios_init(void) > "HPET", sizeof(*hpet), 1); > #endif > > + Stray empty line; might also unite it into one #ifdef #endif pair. > +#ifdef BX_QEMU > + acpi_additional_tables(); /* resets cfg to required entry */ > + for(i = 0; i < ext_tbl; i++) { > + uint16_t len; > + if(addr >= ram_size) > + BX_PANIC("ACPI table overflow\n"); > + if(acpi_load_table(i, addr, &len) < 0) > + BX_PANIC("Fail to load ACPI table from QEMU\n"); Failed? > + rsdt->table_offset_entry[i+4] = cpu_to_le32(addr); > + addr += len; > + } > +#endif > + > + /* RSDT */ > + memset(rsdt, 0, sizeof(*rsdt)); This overwrites the "rsdt->table_offset_entry[i+4] = cpu_to_le32(addr);" assignment from above? > + rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr); > + rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr); > + rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); > +#ifdef BX_QEMU > + rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); > +#endif > + acpi_build_table_header((struct acpi_table_header *)rsdt, > + "RSDT", rsdt_size, 1); > + > + acpi_tables_size = addr - base_addr; > + > + BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n", > + (unsigned long)rsdp, > + (unsigned long)rsdt, acpi_tables_size); > + > } > > /* SMBIOS entry point -- must be written to a 16-bit aligned address > -- - Sebastian ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM 2009-02-09 20:41 ` [Qemu-devel] Re: [Bochs-developers] " Sebastian Herbszt @ 2009-02-09 21:00 ` Gleb Natapov 2009-02-09 21:28 ` Anthony Liguori 0 siblings, 1 reply; 8+ messages in thread From: Gleb Natapov @ 2009-02-09 21:00 UTC (permalink / raw) To: Sebastian Herbszt; +Cc: bochs-developers, qemu-devel On Mon, Feb 09, 2009 at 09:41:07PM +0100, Sebastian Herbszt wrote: > Gleb Natapov wrote: > > Just a quick review. > >> diff --git a/bios/rombios32.c b/bios/rombios32.c >> index f6ce225..29fd40a 100644 >> --- a/bios/rombios32.c >> +++ b/bios/rombios32.c >> @@ -455,6 +455,8 @@ unsigned long bios_table_end_addr; >> #define QEMU_CFG_SIGNATURE 0x00 >> #define QEMU_CFG_ID 0x01 >> #define QEMU_CFG_UUID 0x02 >> +#define FW_CFG_ARCH_LOCAL 0x8000 >> +#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) > > No more QEMU_CFG prefix? Or is this different? > It is not. I'll change it to QEMU_CFG. >> + >> +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) >> +{ >> + qemu_cfg_read((uint8_t*)len, sizeof(*len)); >> + >> + if (!*len) >> + return -1; >> + >> + qemu_cfg_read((uint8_t*)addr, *len); >> + return 0; >> +} >> #endif >> >> void init_smp_msrs(void) > > Can you please diff against bochs cvs? > Will do. This patch was initially intended to go to qemu patch series so I did it against patched bios source. And unpatched bochs bios does not boot linux with qemu. IRQ routing problem or something. >> + rsdt->table_offset_entry[i+4] = cpu_to_le32(addr); >> + addr += len; >> + } >> +#endif >> + >> + /* RSDT */ >> + memset(rsdt, 0, sizeof(*rsdt)); > > This overwrites the "rsdt->table_offset_entry[i+4] = cpu_to_le32(addr);" assignment from above? No since sizeof(*rstd) is less then that. But I'll move memset up, it will be less confusing. -- Gleb. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM 2009-02-09 21:00 ` Gleb Natapov @ 2009-02-09 21:28 ` Anthony Liguori 2009-02-10 7:20 ` Gleb Natapov 0 siblings, 1 reply; 8+ messages in thread From: Anthony Liguori @ 2009-02-09 21:28 UTC (permalink / raw) To: qemu-devel; +Cc: bochs-developers, Sebastian Herbszt Gleb Natapov wrote: >>> + >>> +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) >>> +{ >>> + qemu_cfg_read((uint8_t*)len, sizeof(*len)); >>> + >>> + if (!*len) >>> + return -1; >>> + >>> + qemu_cfg_read((uint8_t*)addr, *len); >>> + return 0; >>> +} >>> #endif >>> >>> void init_smp_msrs(void) >>> >> Can you please diff against bochs cvs? >> >> > Will do. This patch was initially intended to go to qemu patch series so I > did it against patched bios source. I'm happy to update to a more recent BIOS snapshot... > And unpatched bochs bios does not > boot linux with qemu. IRQ routing problem or something. > Unless upstream Bochs has regressed. Did you apply the other patches in the QEMU series? Some are no longer needed I think. Regards, Anthony Liguori > -- > Gleb. > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM 2009-02-09 21:28 ` Anthony Liguori @ 2009-02-10 7:20 ` Gleb Natapov 2009-02-10 20:28 ` Marcelo Tosatti 2009-02-15 22:22 ` [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI " Sebastian Herbszt 0 siblings, 2 replies; 8+ messages in thread From: Gleb Natapov @ 2009-02-10 7:20 UTC (permalink / raw) To: qemu-devel; +Cc: bochs-developers, Sebastian Herbszt On Mon, Feb 09, 2009 at 03:28:52PM -0600, Anthony Liguori wrote: > Gleb Natapov wrote: >>>> + >>>> +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) >>>> +{ >>>> + qemu_cfg_read((uint8_t*)len, sizeof(*len)); >>>> + >>>> + if (!*len) >>>> + return -1; >>>> + >>>> + qemu_cfg_read((uint8_t*)addr, *len); >>>> + return 0; >>>> +} >>>> #endif >>>> >>>> void init_smp_msrs(void) >>>> >>> Can you please diff against bochs cvs? >>> >>> >> Will do. This patch was initially intended to go to qemu patch series so I >> did it against patched bios source. > > I'm happy to update to a more recent BIOS snapshot... > >> And unpatched bochs bios does not >> boot linux with qemu. IRQ routing problem or something. >> > > Unless upstream Bochs has regressed. Did you apply the other patches in > the QEMU series? Some are no longer needed I think. > With all qemu patches IRQ problem goes away. (One qemu patch conflicts with the last bochs commit so I reverted it before applying qemu series). -- Gleb. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additional ACPI tables from a VM 2009-02-10 7:20 ` Gleb Natapov @ 2009-02-10 20:28 ` Marcelo Tosatti 2009-02-15 22:22 ` [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI " Sebastian Herbszt 1 sibling, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2009-02-10 20:28 UTC (permalink / raw) To: qemu-devel, Anthony Liguori; +Cc: bochs-developers, Sebastian Herbszt [-- Attachment #1: Type: text/plain, Size: 1449 bytes --] On Tue, Feb 10, 2009 at 09:20:06AM +0200, Gleb Natapov wrote: > On Mon, Feb 09, 2009 at 03:28:52PM -0600, Anthony Liguori wrote: > > Gleb Natapov wrote: > >>>> + > >>>> +static int acpi_load_table(int i, uint32_t addr, uint16_t *len) > >>>> +{ > >>>> + qemu_cfg_read((uint8_t*)len, sizeof(*len)); > >>>> + > >>>> + if (!*len) > >>>> + return -1; > >>>> + > >>>> + qemu_cfg_read((uint8_t*)addr, *len); > >>>> + return 0; > >>>> +} > >>>> #endif > >>>> > >>>> void init_smp_msrs(void) > >>>> > >>> Can you please diff against bochs cvs? > >>> > >>> > >> Will do. This patch was initially intended to go to qemu patch series so I > >> did it against patched bios source. > > > > I'm happy to update to a more recent BIOS snapshot... > > > >> And unpatched bochs bios does not > >> boot linux with qemu. IRQ routing problem or something. > >> > > > > Unless upstream Bochs has regressed. Did you apply the other patches in > > the QEMU series? Some are no longer needed I think. > > > With all qemu patches IRQ problem goes away. (One qemu patch conflicts with > the last bochs commit so I reverted it before applying qemu series). Ugh, I was getting "GRUB Error 16: Inconsistent filesystem structure" which appeared to be caused by 864034d9a3190e0c2c10382ae015b5b5fd16718a. But now its magically working again. Or not? Anthony, attached are updated patches + series to sync with Bochs. Please give it a try. [-- Attachment #2: 0001_bx-qemu.patch --] [-- Type: text/plain, Size: 301 bytes --] --- bochs-2.3.7.orig/bios/rombios.h +++ bochs-2.3.7/bios/rombios.h @@ -19,7 +19,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /* define it to include QEMU specific code */ -//#define BX_QEMU +#define BX_QEMU #ifndef LEGACY # define BX_ROMBIOS32 1 [-- Attachment #3: 0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch --] [-- Type: text/plain, Size: 2110 bytes --] update SMBIOS table to report memory above 4G (Alex Williamson) Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -429,6 +429,7 @@ uint32_t cpuid_signature; uint32_t cpuid_features; uint32_t cpuid_ext_features; unsigned long ram_size; +uint64_t ram_end; uint8_t bios_uuid[16]; #ifdef BX_USE_EBDA_TABLES unsigned long ebda_cur_addr; @@ -570,6 +571,14 @@ void ram_probe(void) else ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 + 1 * 1024 * 1024; + if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d)) + ram_end = (((uint64_t)cmos_readb(0x5b) << 16) | + ((uint64_t)cmos_readb(0x5c) << 24) | + ((uint64_t)cmos_readb(0x5d) << 32)) + (1ull << 32); + else + ram_end = ram_size; + BX_INFO("end of ram=%ldMB\n", ram_end >> 20); + BX_INFO("ram_size=0x%08lx\n", ram_size); #ifdef BX_USE_EBDA_TABLES ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; @@ -2174,7 +2183,8 @@ void smbios_init(void) { unsigned cpu_num, nr_structs = 0, max_struct_size = 0; char *start, *p, *q; - int memsize = ram_size / (1024 * 1024); + int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : + (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); #ifdef BX_USE_EBDA_TABLES ebda_cur_addr = align(ebda_cur_addr, 16); @@ -2201,8 +2211,8 @@ void smbios_init(void) add_struct(smbios_type_4_init(p, cpu_num)); add_struct(smbios_type_16_init(p, memsize)); add_struct(smbios_type_17_init(p, memsize)); - add_struct(smbios_type_19_init(p, memsize)); - add_struct(smbios_type_20_init(p, memsize)); + add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024))); + add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024))); add_struct(smbios_type_32_init(p)); add_struct(smbios_type_127_init(p)); [-- Attachment #4: 0003_kvm-bios-generate-mptable-unconditionally.patch --] [-- Type: text/plain, Size: 662 bytes --] generate mptable unconditionally (Avi Kivity) VMware ESX requires an mptable even for uniprocessor guests. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -970,11 +970,6 @@ static void mptable_init(void) int ioapic_id, i, len; int mp_config_table_size; -#ifdef BX_QEMU - if (smp_cpus <= 1) - return; -#endif - #ifdef BX_USE_EBDA_TABLES mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE); #else [-- Attachment #5: 0004_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch --] [-- Type: text/plain, Size: 6464 bytes --] resolve memory device roll over reporting issues with >32G guests (Bill Rieske) 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 <brieske@novell.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -381,6 +381,17 @@ int vsnprintf(char *buf, int buflen, con return buf - buf0; } +int snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsnprintf(buf,size,fmt,args); + va_end(args); + return i; +} + void bios_printf(int flags, const char *fmt, ...) { va_list ap; @@ -2039,7 +2050,7 @@ smbios_type_4_init(void *start, unsigned /* Type 16 -- Physical Memory Array */ static void * -smbios_type_16_init(void *start, uint32_t memsize) +smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs) { struct smbios_type_16 *p = (struct smbios_type_16*)start; @@ -2052,7 +2063,7 @@ smbios_type_16_init(void *start, uint32_ p->error_correction = 0x01; /* other */ p->maximum_capacity = memsize * 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); *((uint16_t *)start) = 0; @@ -2062,20 +2073,19 @@ smbios_type_16_init(void *start, uint32_ /* Type 17 -- Memory Device */ static void * -smbios_type_17_init(void *start, uint32_t memory_size_mb) +smbios_type_17_init(void *start, uint32_t 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] */ - p->size = (uint16_t) memory_size_mb & 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; @@ -2084,8 +2094,8 @@ smbios_type_17_init(void *start, uint32_ p->type_detail = 0; start += sizeof(struct smbios_type_17); - memcpy((char *)start, "DIMM 1", 7); - start += 7; + snprintf(start, 8, "DIMM %d", instance); + start += strlen(start) + 1; *((uint8_t *)start) = 0; return start+1; @@ -2093,16 +2103,16 @@ smbios_type_17_init(void *start, uint32_ /* Type 19 -- Memory Array Mapped Address */ static void * -smbios_type_19_init(void *start, uint32_t memory_size_mb) +smbios_type_19_init(void *start, uint32_t 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; - p->ending_address = (memory_size_mb * 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; @@ -2114,18 +2124,18 @@ smbios_type_19_init(void *start, uint32_ /* Type 20 -- Memory Device Mapped Address */ static void * -smbios_type_20_init(void *start, uint32_t memory_size_mb) +smbios_type_20_init(void *start, uint32_t 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; - p->ending_address = (memory_size_mb * 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; @@ -2176,6 +2186,7 @@ void smbios_init(void) char *start, *p, *q; int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) : (ram_end - (1ull << 32) + ram_size) / (1024 * 1024); + int i, nr_mem_devs; #ifdef BX_USE_EBDA_TABLES ebda_cur_addr = align(ebda_cur_addr, 16); @@ -2187,23 +2198,32 @@ void smbios_init(void) p = (char *)start + sizeof(struct smbios_entry_point); -#define add_struct(fn) { \ +#define add_struct(fn) do{ \ q = (fn); \ nr_structs++; \ if ((q - p) > max_struct_size) \ max_struct_size = q - p; \ p = q; \ -} +}while (0) add_struct(smbios_type_0_init(p)); add_struct(smbios_type_1_init(p)); add_struct(smbios_type_3_init(p)); 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, memsize)); - add_struct(smbios_type_17_init(p, memsize)); - add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024))); - add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024))); + + /* Each 'memory device' covers up to 16GB of address space. */ + nr_mem_devs = (memsize + 0x3fff) >> 14; + add_struct(smbios_type_16_init(p, memsize, nr_mem_devs)); + for ( i = 0; i < nr_mem_devs; i++ ) + { + uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) + ? (memsize & 0x3fff) : 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)); [-- Attachment #6: 0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch --] [-- Type: text/plain, Size: 919 bytes --] fix smbios memory device length boundary condition (Bill Rieske) dev_memsize ends up 0 when it shouldn't be on 16G boundary conditions. Signed-off-by: Bill Rieske <brieske@novell.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Index: bochs/bios/rombios32.c =================================================================== --- bochs.orig/bios/rombios32.c +++ bochs/bios/rombios32.c @@ -2218,7 +2218,7 @@ void smbios_init(void) for ( i = 0; i < nr_mem_devs; i++ ) { uint32_t dev_memsize = ((i == (nr_mem_devs - 1)) - ? (memsize & 0x3fff) : 0x4000); + ? (((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)); [-- Attachment #7: series --] [-- Type: text/plain, Size: 296 bytes --] 0001_bx-qemu.patch 0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch 0003_kvm-bios-generate-mptable-unconditionally.patch 0004_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch 0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI tables from a VM 2009-02-10 7:20 ` Gleb Natapov 2009-02-10 20:28 ` Marcelo Tosatti @ 2009-02-15 22:22 ` Sebastian Herbszt 2009-02-16 10:14 ` Gleb Natapov 1 sibling, 1 reply; 8+ messages in thread From: Sebastian Herbszt @ 2009-02-15 22:22 UTC (permalink / raw) To: Gleb Natapov, qemu-devel; +Cc: bochs-developers Gleb Natapov wrote: > On Mon, Feb 09, 2009 at 03:28:52PM -0600, Anthony Liguori wrote: >> Gleb Natapov wrote: >>> And unpatched bochs bios does not >>> boot linux with qemu. IRQ routing problem or something. >>> >> >> Unless upstream Bochs has regressed. Did you apply the other patches in >> the QEMU series? Some are no longer needed I think. >> > With all qemu patches IRQ problem goes away. (One qemu patch conflicts with > the last bochs commit so I reverted it before applying qemu series). Can you please try upstream bochs with only 0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch applied from the qemu bios patch queue? - Sebastian ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI tables from a VM 2009-02-15 22:22 ` [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI " Sebastian Herbszt @ 2009-02-16 10:14 ` Gleb Natapov 0 siblings, 0 replies; 8+ messages in thread From: Gleb Natapov @ 2009-02-16 10:14 UTC (permalink / raw) To: Sebastian Herbszt; +Cc: bochs-developers, qemu-devel On Sun, Feb 15, 2009 at 11:22:18PM +0100, Sebastian Herbszt wrote: > Gleb Natapov wrote: >> On Mon, Feb 09, 2009 at 03:28:52PM -0600, Anthony Liguori wrote: >>> Gleb Natapov wrote: >>>> And unpatched bochs bios does not >>>> boot linux with qemu. IRQ routing problem or something. >>>> >>> >>> Unless upstream Bochs has regressed. Did you apply the other patches >>> in the QEMU series? Some are no longer needed I think. >>> >> With all qemu patches IRQ problem goes away. (One qemu patch conflicts with >> the last bochs commit so I reverted it before applying qemu series). > > Can you please try upstream bochs with only 0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch > applied from the qemu bios patch queue? > For some strange reason this no longer happens. May be something in qemu changed. -- Gleb. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-02-16 10:17 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-02-09 14:30 [Qemu-devel] [PATCH] Read additional ACPI tables from a VM Gleb Natapov 2009-02-09 20:41 ` [Qemu-devel] Re: [Bochs-developers] " Sebastian Herbszt 2009-02-09 21:00 ` Gleb Natapov 2009-02-09 21:28 ` Anthony Liguori 2009-02-10 7:20 ` Gleb Natapov 2009-02-10 20:28 ` Marcelo Tosatti 2009-02-15 22:22 ` [Qemu-devel] Re: [Bochs-developers] [PATCH] Read additionalACPI " Sebastian Herbszt 2009-02-16 10:14 ` Gleb Natapov
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).