qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [6392] Add BIOS fixes from KVM tree


From: Anthony Liguori
Subject: [Qemu-devel] [6392] Add BIOS fixes from KVM tree
Date: Wed, 21 Jan 2009 21:46:20 +0000

Revision: 6392
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6392
Author:   aliguori
Date:     2009-01-21 21:46:20 +0000 (Wed, 21 Jan 2009)

Log Message:
-----------
Add BIOS fixes from KVM tree

See each patch for individual Signed-off-by's/commit logs

Modified Paths:
--------------
    trunk/pc-bios/bios-pq/HEAD
    trunk/pc-bios/bios-pq/series
    trunk/pc-bios/bios.bin

Added Paths:
-----------
    
trunk/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
    trunk/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch
    trunk/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch
    trunk/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch
    trunk/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch
    
trunk/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch
    
trunk/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch
    
trunk/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
    
trunk/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch

Added: 
trunk/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
===================================================================
--- 
trunk/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
                             (rev 0)
+++ 
trunk/pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
     2009-01-21 21:46:20 UTC (rev 6392)
@@ -0,0 +1,33 @@
+update SMBIOS table to report memory above 4G (Alex Williamson)
+
+Signed-off-by: Alex Williamson <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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));
+
+
+

Added: 
trunk/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch
===================================================================
--- trunk/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch  
                        (rev 0)
+++ trunk/pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch  
2009-01-21 21:46:20 UTC (rev 6392)
@@ -0,0 +1,25 @@
+generate mptable unconditionally (Avi Kivity)
+
+VMware ESX requires an mptable even for uniprocessor guests.
+
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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
+
+

Added: trunk/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch
===================================================================
--- trunk/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch                  
        (rev 0)
+++ trunk/pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch  2009-01-21 
21:46:20 UTC (rev 6392)
@@ -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 <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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();
+ }
+
+ /****************************************************/
+
+

Added: trunk/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch
===================================================================
--- trunk/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch                  
        (rev 0)
+++ trunk/pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch  2009-01-21 
21:46:20 UTC (rev 6392)
@@ -0,0 +1,126 @@
+smp mtrr support (Avi Kivity)
+
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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
+
+

Added: trunk/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch
===================================================================
--- trunk/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch          
                (rev 0)
+++ trunk/pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch  
2009-01-21 21:46:20 UTC (rev 6392)
@@ -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 <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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();
+ }
+
+
+

Added: 
trunk/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch
===================================================================
--- 
trunk/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch
                               (rev 0)
+++ 
trunk/pc-bios/bios-pq/0007_kvm-bios-cleanup-consolidate-above-4g-memory-parsing.patch
       2009-01-21 21:46:20 UTC (rev 6392)
@@ -0,0 +1,58 @@
+cleanup/consolidate above 4G memory parsing (Alex Williamson)
+
+Signed-off-by: Alex Williamson <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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();
+ }
+
+
+

Added: 
trunk/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch
===================================================================
--- 
trunk/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch
                               (rev 0)
+++ 
trunk/pc-bios/bios-pq/0008_kvm-bios-switch-mtrrs-to-cover-only-the-pci-range-and--default-to-wb.patch
       2009-01-21 21:46:20 UTC (rev 6392)
@@ -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 <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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)
+
+
+

Added: 
trunk/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
===================================================================
--- 
trunk/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
                         (rev 0)
+++ 
trunk/pc-bios/bios-pq/0009_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
 2009-01-21 21:46:20 UTC (rev 6392)
@@ -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 <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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));
+
+
+

Added: 
trunk/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch
===================================================================
--- 
trunk/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch
                               (rev 0)
+++ 
trunk/pc-bios/bios-pq/0010_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch
       2009-01-21 21:46:20 UTC (rev 6392)
@@ -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 <address@hidden>
+Signed-off-by: Avi Kivity <address@hidden>
+Signed-off-by: Anthony Liguori <address@hidden>
+
+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));
+
+

Modified: trunk/pc-bios/bios-pq/HEAD
===================================================================
--- trunk/pc-bios/bios-pq/HEAD  2009-01-21 19:28:13 UTC (rev 6391)
+++ trunk/pc-bios/bios-pq/HEAD  2009-01-21 21:46:20 UTC (rev 6392)
@@ -1 +1 @@
-7342176bb0fa9d6cc63b37f6ac239e3f70b74219
+36989b0d2e785ac9e5d6e8a226dbdeb82e876bfd

Modified: trunk/pc-bios/bios-pq/series
===================================================================
--- trunk/pc-bios/bios-pq/series        2009-01-21 19:28:13 UTC (rev 6391)
+++ trunk/pc-bios/bios-pq/series        2009-01-21 21:46:20 UTC (rev 6392)
@@ -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

Modified: trunk/pc-bios/bios.bin
===================================================================
(Binary files differ)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]