From 9a717b55df29b2b0dd0553ccfa656671bad043d1 Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 21 Jan 2009 21:46:20 +0000 Subject: [PATCH] Add BIOS fixes from KVM tree See each patch for individual Signed-off-by's/commit logs git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6392 c046a42c-6fe2-441c-8c8c-71466251a162 --- ...bios-table-to-report-memory-above-4g.patch | 33 ++++ ...ios-generate-mptable-unconditionally.patch | 25 +++ .../0004_kvm-bios-add-mtrr-support.patch | 120 ++++++++++++ .../0005_kvm-bios-smp-mtrr-support.patch | 126 ++++++++++++ ...06_kvm-bios-extend-mtrrs-to-above-4g.patch | 62 ++++++ ...-consolidate-above-4g-memory-parsing.patch | 58 ++++++ ...nly-the-pci-range-and--default-to-wb.patch | 54 +++++ ...er-reporting--issues-with-32g-guests.patch | 184 ++++++++++++++++++ ...ry-device-length-boundary--condition.patch | 23 +++ pc-bios/bios-pq/HEAD | 2 +- pc-bios/bios-pq/series | 9 + pc-bios/bios.bin | Bin 131072 -> 131072 bytes 12 files changed, 695 insertions(+), 1 deletion(-) create mode 100644 pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch create mode 100644 pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch create mode 100644 pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch create mode 100644 pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch create mode 100644 pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch create mode 100644 pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch create mode 100644 pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch create mode 100644 pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch create mode 100644 pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch diff --git a/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch b/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch new file mode 100644 index 00000000000..d84c49f8edb --- /dev/null +++ b/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch @@ -0,0 +1,33 @@ +update SMBIOS table to report memory above 4G (Alex Williamson) + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -2081,7 +2081,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); +@@ -2108,8 +2109,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)); + + + diff --git a/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch b/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch new file mode 100644 index 00000000000..7826a86d0e2 --- /dev/null +++ b/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch @@ -0,0 +1,25 @@ +generate mptable unconditionally (Avi Kivity) + +VMware ESX requires an mptable even for uniprocessor guests. + +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +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 + + diff --git a/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch b/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch new file mode 100644 index 00000000000..e5d4d7452c2 --- /dev/null +++ b/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch @@ -0,0 +1,120 @@ +add mtrr support (Avi Kivity) + +program mtrrs for cpu 0. Doesn't support >=4G at the moment. + +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -64,6 +64,23 @@ typedef unsigned long long uint64_t; + + #define BIOS_TMP_STORAGE 0x00030000 /* 64 KB used to copy the BIOS to shadow RAM */ + ++#define MSR_MTRRcap 0x000000fe ++#define MSR_MTRRfix64K_00000 0x00000250 ++#define MSR_MTRRfix16K_80000 0x00000258 ++#define MSR_MTRRfix16K_A0000 0x00000259 ++#define MSR_MTRRfix4K_C0000 0x00000268 ++#define MSR_MTRRfix4K_C8000 0x00000269 ++#define MSR_MTRRfix4K_D0000 0x0000026a ++#define MSR_MTRRfix4K_D8000 0x0000026b ++#define MSR_MTRRfix4K_E0000 0x0000026c ++#define MSR_MTRRfix4K_E8000 0x0000026d ++#define MSR_MTRRfix4K_F0000 0x0000026e ++#define MSR_MTRRfix4K_F8000 0x0000026f ++#define MSR_MTRRdefType 0x000002ff ++ ++#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) ++#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) ++ + static inline void outl(int addr, int val) + { + asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val)); +@@ -135,6 +152,19 @@ static inline void putc(int c) + outb(INFO_PORT, c); + } + ++static uint64_t rdmsr(unsigned index) ++{ ++ unsigned long long ret; ++ ++ asm ("rdmsr" : "=A"(ret) : "c"(index)); ++ return ret; ++} ++ ++static void wrmsr(unsigned index, uint64_t val) ++{ ++ asm volatile ("wrmsr" : : "c"(index), "A"(val)); ++} ++ + static inline int isdigit(int c) + { + return c >= '0' && c <= '9'; +@@ -469,6 +499,54 @@ static int cmos_readb(int addr) + return inb(0x71); + } + ++void setup_mtrr(void) ++{ ++ int i, vcnt, fix, wc; ++ uint32_t mtrr_cap; ++ union { ++ uint8_t valb[8]; ++ uint64_t val; ++ } u; ++ uint64_t vbase, vmask; ++ ++ mtrr_cap = rdmsr(MSR_MTRRcap); ++ vcnt = mtrr_cap & 0xff; ++ fix = mtrr_cap & 0x100; ++ wc = mtrr_cap & 0x400; ++ if (!vcnt || !fix) ++ return; ++ u.val = 0; ++ for (i = 0; i < 8; ++i) ++ if (ram_size >= 65536 * (i + 1)) ++ u.valb[i] = 6; ++ wrmsr(MSR_MTRRfix64K_00000, u.val); ++ u.val = 0; ++ for (i = 0; i < 8; ++i) ++ if (ram_size >= 65536 * 8 + 16384 * (i + 1)) ++ u.valb[i] = 6; ++ wrmsr(MSR_MTRRfix16K_80000, u.val); ++ wrmsr(MSR_MTRRfix16K_A0000, 0); ++ wrmsr(MSR_MTRRfix4K_C0000, 0); ++ wrmsr(MSR_MTRRfix4K_C8000, 0); ++ wrmsr(MSR_MTRRfix4K_D0000, 0); ++ wrmsr(MSR_MTRRfix4K_D8000, 0); ++ wrmsr(MSR_MTRRfix4K_E0000, 0); ++ wrmsr(MSR_MTRRfix4K_E8000, 0); ++ wrmsr(MSR_MTRRfix4K_F0000, 0); ++ wrmsr(MSR_MTRRfix4K_F8000, 0); ++ vbase = 0; ++ --vcnt; /* leave one mtrr for VRAM */ ++ for (i = 0; i < vcnt && vbase < ram_size; ++i) { ++ vmask = (1ull << 40) - 1; ++ while (vbase + vmask + 1 > ram_size) ++ vmask >>= 1; ++ wrmsr(MTRRphysBase_MSR(i), vbase | 6); ++ wrmsr(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); ++ vbase += vmask + 1; ++ } ++ wrmsr(MSR_MTRRdefType, 0xc00); ++} ++ + void ram_probe(void) + { + if (cmos_readb(0x34) | cmos_readb(0x35)) +@@ -482,6 +560,7 @@ void ram_probe(void) + ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + #endif ++ setup_mtrr(); + } + + /****************************************************/ + + diff --git a/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch b/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch new file mode 100644 index 00000000000..ee867a0ac41 --- /dev/null +++ b/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch @@ -0,0 +1,126 @@ +smp mtrr support (Avi Kivity) + +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios.h +=================================================================== +--- bochs.orig/bios/rombios.h ++++ bochs/bios/rombios.h +@@ -56,6 +56,7 @@ + #define ACPI_DATA_SIZE 0x00010000L + #define PM_IO_BASE 0xb000 + #define SMB_IO_BASE 0xb100 ++#define SMP_MSR_ADDR 0xf010 + + // Define the application NAME + #if defined(BX_QEMU) +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -472,6 +472,23 @@ void qemu_cfg_read(uint8_t *buf, int len + } + #endif + ++void init_smp_msrs(void) ++{ ++ *(uint32_t *)SMP_MSR_ADDR = 0; ++} ++ ++void wrmsr_smp(uint32_t index, uint64_t val) ++{ ++ static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR; ++ ++ wrmsr(index, val); ++ p->ecx = index; ++ p->eax = val; ++ p->edx = val >> 32; ++ ++p; ++ p->ecx = 0; ++} ++ + void uuid_probe(void) + { + #ifdef BX_QEMU +@@ -519,32 +536,32 @@ void setup_mtrr(void) + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * (i + 1)) + u.valb[i] = 6; +- wrmsr(MSR_MTRRfix64K_00000, u.val); ++ wrmsr_smp(MSR_MTRRfix64K_00000, u.val); + u.val = 0; + for (i = 0; i < 8; ++i) + if (ram_size >= 65536 * 8 + 16384 * (i + 1)) + u.valb[i] = 6; +- wrmsr(MSR_MTRRfix16K_80000, u.val); +- wrmsr(MSR_MTRRfix16K_A0000, 0); +- wrmsr(MSR_MTRRfix4K_C0000, 0); +- wrmsr(MSR_MTRRfix4K_C8000, 0); +- wrmsr(MSR_MTRRfix4K_D0000, 0); +- wrmsr(MSR_MTRRfix4K_D8000, 0); +- wrmsr(MSR_MTRRfix4K_E0000, 0); +- wrmsr(MSR_MTRRfix4K_E8000, 0); +- wrmsr(MSR_MTRRfix4K_F0000, 0); +- wrmsr(MSR_MTRRfix4K_F8000, 0); ++ wrmsr_smp(MSR_MTRRfix16K_80000, u.val); ++ wrmsr_smp(MSR_MTRRfix16K_A0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_C0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_C8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_D0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_D8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_E0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_E8000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_F0000, 0); ++ wrmsr_smp(MSR_MTRRfix4K_F8000, 0); + vbase = 0; + --vcnt; /* leave one mtrr for VRAM */ + for (i = 0; i < vcnt && vbase < ram_size; ++i) { + vmask = (1ull << 40) - 1; + while (vbase + vmask + 1 > ram_size) + vmask >>= 1; +- wrmsr(MTRRphysBase_MSR(i), vbase | 6); +- wrmsr(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); ++ wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); ++ wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } +- wrmsr(MSR_MTRRdefType, 0xc00); ++ wrmsr_smp(MSR_MTRRdefType, 0xc00); + } + + void ram_probe(void) +@@ -2263,6 +2280,8 @@ void rombios32_init(uint32_t *s3_resume_ + qemu_cfg_port = qemu_cfg_port_probe(); + #endif + ++ init_smp_msrs(); ++ + ram_probe(); + + cpu_probe(); +Index: bochs/bios/rombios32start.S +=================================================================== +--- bochs.orig/bios/rombios32start.S ++++ bochs/bios/rombios32start.S +@@ -49,6 +49,18 @@ _start: + smp_ap_boot_code_start: + xor %ax, %ax + mov %ax, %ds ++ ++ mov $SMP_MSR_ADDR, %ebx ++11: ++ mov 0(%ebx), %ecx ++ test %ecx, %ecx ++ jz 12f ++ mov 4(%ebx), %eax ++ mov 8(%ebx), %edx ++ wrmsr ++ add $12, %ebx ++ jmp 11b ++12: + lock incw smp_cpus + 1: + hlt + + diff --git a/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch b/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch new file mode 100644 index 00000000000..7350b47992c --- /dev/null +++ b/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch @@ -0,0 +1,62 @@ +extend MTRRs to above 4G (Alex Williamson) + +When I try to boot guests using a recent Linux kernel (2.6.26+), memory +above 3.5G gets thrown away with an error like this: + +WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing 4608MB of RAM + +This extends MTRRs to cover all of memory. + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -427,6 +427,7 @@ uint32_t cpuid_signature; + uint32_t cpuid_features; + uint32_t cpuid_ext_features; + unsigned long ram_size; ++uint64_t above4g_ram_size; + uint8_t bios_uuid[16]; + #ifdef BX_USE_EBDA_TABLES + unsigned long ebda_cur_addr; +@@ -561,6 +562,14 @@ void setup_mtrr(void) + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } ++ for (vbase = 1ull << 32; i < vcnt && vbase < above4g_ram_size; ++i) { ++ vmask = (1ull << 40) - 1; ++ while (vbase + vmask + 1 > above4g_ram_size) ++ vmask >>= 1; ++ wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); ++ wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); ++ vbase += vmask + 1; ++ } + wrmsr_smp(MSR_MTRRdefType, 0xc00); + } + +@@ -572,11 +581,19 @@ 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)) ++ above4g_ram_size = ((uint64_t)cmos_readb(0x5b) << 16) | ++ ((uint64_t)cmos_readb(0x5c) << 24) | ((uint64_t)cmos_readb(0x5d) << 32); ++ ++ if (above4g_ram_size) ++ above4g_ram_size += 1ull << 32; ++ + BX_INFO("ram_size=0x%08lx\n", ram_size); + #ifdef BX_USE_EBDA_TABLES + ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + #endif ++ BX_INFO("top of ram %ldMB\n", above4g_ram_size >> 20); + setup_mtrr(); + } + + + diff --git a/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch b/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch new file mode 100644 index 00000000000..3ce0c05b3ca --- /dev/null +++ b/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch @@ -0,0 +1,58 @@ +cleanup/consolidate above 4G memory parsing (Alex Williamson) + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -427,7 +427,7 @@ uint32_t cpuid_signature; + uint32_t cpuid_features; + uint32_t cpuid_ext_features; + unsigned long ram_size; +-uint64_t above4g_ram_size; ++uint64_t ram_end; + uint8_t bios_uuid[16]; + #ifdef BX_USE_EBDA_TABLES + unsigned long ebda_cur_addr; +@@ -562,9 +562,9 @@ void setup_mtrr(void) + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); + vbase += vmask + 1; + } +- for (vbase = 1ull << 32; i < vcnt && vbase < above4g_ram_size; ++i) { ++ for (vbase = 1ull << 32; i < vcnt && vbase < ram_end; ++i) { + vmask = (1ull << 40) - 1; +- while (vbase + vmask + 1 > above4g_ram_size) ++ while (vbase + vmask + 1 > ram_end) + vmask >>= 1; + wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); + wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +@@ -582,18 +582,19 @@ void ram_probe(void) + ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 + + 1 * 1024 * 1024; + if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d)) +- above4g_ram_size = ((uint64_t)cmos_readb(0x5b) << 16) | +- ((uint64_t)cmos_readb(0x5c) << 24) | ((uint64_t)cmos_readb(0x5d) << 32); ++ 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; + +- if (above4g_ram_size) +- above4g_ram_size += 1ull << 32; ++ 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; + BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); + #endif +- BX_INFO("top of ram %ldMB\n", above4g_ram_size >> 20); + setup_mtrr(); + } + + + diff --git a/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch b/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch new file mode 100644 index 00000000000..caf9aee9941 --- /dev/null +++ b/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch @@ -0,0 +1,54 @@ +switch MTRRs to cover only the PCI range and default to WB (Alex Williamson) + +This matches how some bare metal machines report MTRRs and avoids +the problem of running out of MTRRs to cover all of RAM. + +Signed-off-by: Alex Williamson +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +Index: bochs/bios/rombios32.c +=================================================================== +--- bochs.orig/bios/rombios32.c ++++ bochs/bios/rombios32.c +@@ -525,7 +525,6 @@ void setup_mtrr(void) + uint8_t valb[8]; + uint64_t val; + } u; +- uint64_t vbase, vmask; + + mtrr_cap = rdmsr(MSR_MTRRcap); + vcnt = mtrr_cap & 0xff; +@@ -552,25 +551,10 @@ void setup_mtrr(void) + wrmsr_smp(MSR_MTRRfix4K_E8000, 0); + wrmsr_smp(MSR_MTRRfix4K_F0000, 0); + wrmsr_smp(MSR_MTRRfix4K_F8000, 0); +- vbase = 0; +- --vcnt; /* leave one mtrr for VRAM */ +- for (i = 0; i < vcnt && vbase < ram_size; ++i) { +- vmask = (1ull << 40) - 1; +- while (vbase + vmask + 1 > ram_size) +- vmask >>= 1; +- wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); +- wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +- vbase += vmask + 1; +- } +- for (vbase = 1ull << 32; i < vcnt && vbase < ram_end; ++i) { +- vmask = (1ull << 40) - 1; +- while (vbase + vmask + 1 > ram_end) +- vmask >>= 1; +- wrmsr_smp(MTRRphysBase_MSR(i), vbase | 6); +- wrmsr_smp(MTRRphysMask_MSR(i), (~vmask & 0xfffffff000ull) | 0x800); +- vbase += vmask + 1; +- } +- wrmsr_smp(MSR_MTRRdefType, 0xc00); ++ /* Mark 3.5-4GB as UC, anything not specified defaults to WB */ ++ wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0); ++ wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800); ++ wrmsr_smp(MSR_MTRRdefType, 0xc06); + } + + void ram_probe(void) + + + diff --git a/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch b/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch new file mode 100644 index 00000000000..070d610d361 --- /dev/null +++ b/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch @@ -0,0 +1,184 @@ +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 +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +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)); + + + diff --git a/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch b/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch new file mode 100644 index 00000000000..e4ec229baec --- /dev/null +++ b/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch @@ -0,0 +1,23 @@ +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 +Signed-off-by: Avi Kivity +Signed-off-by: Anthony Liguori + +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)); + + diff --git a/pc-bios/bios-pq/HEAD b/pc-bios/bios-pq/HEAD index 1f604ae8218..23fbe2be3ca 100644 --- a/pc-bios/bios-pq/HEAD +++ b/pc-bios/bios-pq/HEAD @@ -1 +1 @@ -7342176bb0fa9d6cc63b37f6ac239e3f70b74219 +36989b0d2e785ac9e5d6e8a226dbdeb82e876bfd diff --git a/pc-bios/bios-pq/series b/pc-bios/bios-pq/series index 556c0e48dc4..728d0416443 100644 --- a/pc-bios/bios-pq/series +++ b/pc-bios/bios-pq/series @@ -1 +1,10 @@ 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-add-mtrr-support.patch +0005_kvm-bios-smp-mtrr-support.patch +0006_kvm-bios-extend-mtrrs-to-above-4g.patch +0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch +0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch +0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch +0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index ac444c1492d7993d0ae5bc64cbbf6bf2cd2ac39e..9e60f8d95e0b2c38b470cba9a5b212d7a997afd7 100644 GIT binary patch delta 4568 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 delta 3164 zc-nPVeNYtV8Gm>0_E_M!-Q&Z6f}C*j;ho9~){vHX=W%yh1CpY2ri#Q&ylQ7U)ygHc z2?1O+?3~-sy#A9;Gc6&1w4F?ALWa*7xKn0NCvobK&NOQOAT6PXUgeCaU=7>n-Q~;L zGTgh*`}KVOp67Yn+Ss->woC|*pd^F__QFs)ckd6w6B{i^UqbrQ2UGpI2npd|e34L1 z&R@RR^wFO_py{>(ywC6@EjW6fHTF{U4hK#!IkeA#Q%&A=p|o7M+g}00KIyCaGgq3o z_R|QVL7qVovV?ZpZH#$?Ob2}@Fzjf`n! zFv11gmi!iL2KwXKE*^6!-+JZ{vLGqaK2-tV<{V*6eid=Orz-G)l#|c2FYFz9V($=+ zrwnbk1CuC2OhsWr83~0@qDocOx4T)Gy_OPXSbeoKYP4U-v7p#?*aiAp7M@JqMEf0h zl{tT7jl+V1|KfU?9Y6?U!j%pW4>J$UIy_dOsx>MdD6a#*Y~Enop)KSt9m-oev{pa# zp?N#y#BuXYy4HcOr1d57#0yns{FY^y-gY1RxffrybrBmPu}sN3-bLIeALE3uIGK=Z z^QEoYLPM!k6Awh)5Cg@Rj}$kRt+A*%DZiY#zG5HJd};=^G+xpu*1U`6px7tF!S(DLIKG`ckRTfYjY?YUca`awetx@ zQw#Mtc_-xE#bS6gRGEuLi&{J%Oc8%F}m_1C+>!TOP4_#1@ZDu ztKye`Fo0}@={$=E6h0nQc~2LumXRDvdSm3 zAPQMv!MOBqEizUZjf8=lb)mp|6)w3`fRfy1#cfGe+#JM>hnQL6o1O%_8IYsI>3SrH zZ5;;j64gF;Sc`<>PeO7NE4CzBb2ZUM;_?gX(6Yo6CYS6c@;MfqYjwlImDt4BU{R*_|16X{Tk+2Dohp6Ft^U#ZzPh zBU1yd#6Fw+Nf9}s7GqO8Pai<{pBye%35}>96OQYgWYt`5iAArLYQxl{^ zfFy>G0_ukvMFVvND8znrJ_EQkq4-k3aXuE1NWk1m(9D3iT7K|HaN`Ly z{6uq>G#jdk3uA%Ogc!?*tE&hGYO@vJTD#&iLOz&aF&Fsxve1GdbY_{BCVcQd*IUax zydm7|XfOiG=lD0RP-67`%1G;j1JdUYZ+0BaDt#z5+gZKFMXT+`V;~x;2=QF3?~$sC zqqhAAn;I|OPU~Fx2PO3T4fSH&sb}}kIPsqe*>CSAvo1USBe$uk>WGD-~vQi_L-$>-RABUo;(h|fEvGO%PCtS zzG__$W%Qo4jvjVkZ@QO0HG|Kk3zkbOwD!#4Pt!%qYVzH2QIXO zN}%!iw$G?;^6js{M{*hjvIo*3FkIhQ<+b3K1Vanpy}9ftt}jdi5!;@?(>Xas4a3J^ zv0nNbyD&{uH}5}48h-g| zCrb|A{=M9b%>}Es&94a5ci|-0Ya&e2oli2^JWW8h@bDObUe;KUSLGw1p6DlW?Rge`QNCvn6h1qH1n_ZGod0q&MFSt+Z8Ebg_N7u9+b zg4Oo?Ja_s%Xl5~VTUE6TJ`)ad;%KfO5*?-sosZ(q{+T9EA8w!$>=4Hjk~bk;)H1!l z4$hGp4~amfK?0r*2k$C08hGA`4;MOUzZ1Vx_#D9eYT*{j`Hubg7Oj0<%&d&Oab7V% z&8G+VI<>}$`gajtB!@{ZM>JMidFZykpS>Rr8JLBKM1K=GIhlZm1a4g4;n(bjA_lgb ziS6fBK<#xfFxK!D40nMFRlPuLRk<@Q;8-p>R7HR~KmZO;Hb+tUD~o0DrT+>Uv*@UA zGsL6ZS@|)5-fJEuvb@?;Y{7j~H*TqFfV|3HN`+V1-zEVDPYc?rJH7d2sH#M_3Jj{8 zKXEkBDcu_&g^wG~fX2xUlaf|>F}SOJ4m+@;cwMV~S+$t`7SV#e29g%VuLFUdqQX}` zeC=K6A5nrJP|2s>kGtf1thG$o4F6lo%C@2ET{Sf}0dEkBF)lmA{`Am~n@$}4 u`C;rA&h`97c!lb5mydkbQ&--|d_o1T(?WUQk?T}v5i68$E~`Y3FZ>6