qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] MTRR+SMBIOS Bochs patches
@ 2009-01-20  1:28 Marcelo Tosatti
  2009-01-20  2:06 ` [Qemu-devel] " Anthony Liguori
  0 siblings, 1 reply; 3+ messages in thread
From: Marcelo Tosatti @ 2009-01-20  1:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Avi Kivity

[-- Attachment #1: Type: text/plain, Size: 693 bytes --]


Attached patch adds a series of patches against Bochs, from KVM tree: 
  - SMBIOS updates
  - MTRR support
  - unconditional mptable

Alex Williamson (4):
     kvm: bios: extend MTRRs to above 4G
     kvm: bios: cleanup/consolidate above 4G memory parsing
     kvm: bios: update SMBIOS table to report memory above 4G
     kvm: bios: switch MTRRs to cover only the PCI range and default to WB

Avi Kivity (3):
     kvm: bios: generate mptable unconditionally
     kvm: bios: add mtrr support
     kvm: bios: smp mtrr support

Bill Rieske (2):
     kvm: bios: resolve memory device roll over reporting issues with >32 guests
     kvm: bios: fix smbios memory device length boundary condition


[-- Attachment #2: kvm-bios-misc-and-mtrr.patch --]
[-- Type: text/plain, Size: 25968 bytes --]

diff -Nur pc-bios.orig/bios-pq/0002_smbios_report_4g.patch pc-bios/bios-pq/0002_smbios_report_4g.patch
--- pc-bios.orig/bios-pq/0002_smbios_report_4g.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0002_smbios_report_4g.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,32 @@
+kvm: bios: update SMBIOS table to report memory above 4G
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+
+From: Alex Williamson <alex.williamson@hp.com>
+
+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 -Nur pc-bios.orig/bios-pq/0003_mptable_unconditional.patch pc-bios/bios-pq/0003_mptable_unconditional.patch
--- pc-bios.orig/bios-pq/0003_mptable_unconditional.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0003_mptable_unconditional.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,23 @@
+kvm: bios: generate mptable unconditionally
+
+VMware ESX requires an mptable even for uniprocessor guests.
+
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+From: Avi Kivity <avi@qumranet.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
diff -Nur pc-bios.orig/bios-pq/0004_mtrr_up.patch pc-bios/bios-pq/0004_mtrr_up.patch
--- pc-bios.orig/bios-pq/0004_mtrr_up.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0004_mtrr_up.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,119 @@
+kvm: bios: add mtrr support
+
+program mtrrs for cpu 0.  Doesn't support >=4G at the moment.
+    
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+
+From: Avi Kivity <avi@qumranet.com>
+
+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 -Nur pc-bios.orig/bios-pq/0005_mtrr_smp.patch pc-bios/bios-pq/0005_mtrr_smp.patch
--- pc-bios.orig/bios-pq/0005_mtrr_smp.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0005_mtrr_smp.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,125 @@
+kvm: bios: smp mtrr support
+
+Signed-off-by: Avi Kivity <avi@qumranet.com>
+
+From: Avi Kivity <avi@qumranet.com>
+
+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 -Nur pc-bios.orig/bios-pq/0006_mtrr_above_4g.patch pc-bios/bios-pq/0006_mtrr_above_4g.patch
--- pc-bios.orig/bios-pq/0006_mtrr_above_4g.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0006_mtrr_above_4g.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,61 @@
+kvm: bios: extend MTRRs to above 4G
+
+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 <alex.williamson@hp.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+
+From: Alex Williamson <alex.williamson@hp.com>
+
+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 -Nur pc-bios.orig/bios-pq/0007_mtrr_above_4g_clean.patch pc-bios/bios-pq/0007_mtrr_above_4g_clean.patch
--- pc-bios.orig/bios-pq/0007_mtrr_above_4g_clean.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0007_mtrr_above_4g_clean.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,57 @@
+kvm: bios: cleanup/consolidate above 4G memory parsing
+
+Signed-off-by: Alex Williamson <alex.williamson@hp.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+ 
+From: Alex Williamson <alex.williamson@hp.com>
+
+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 -Nur pc-bios.orig/bios-pq/0008_mtrr_default.patch pc-bios/bios-pq/0008_mtrr_default.patch
--- pc-bios.orig/bios-pq/0008_mtrr_default.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0008_mtrr_default.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,52 @@
+kvm: bios: switch MTRRs to cover only the PCI range and default to WB
+    
+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 <alex.williamson@hp.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+
+From: Alex Williamson <alex.williamson@hp.com>
+
+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 -Nur pc-bios.orig/bios-pq/0009_smbios_16gb.patch pc-bios/bios-pq/0009_smbios_16gb.patch
--- pc-bios.orig/bios-pq/0009_smbios_16gb.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0009_smbios_16gb.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,183 @@
+kvm: bios: resolve memory device roll over reporting issues with >32G guests
+
+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>
+
+From: Bill Rieske <brieske@novell.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));
+ 
diff -Nur pc-bios.orig/bios-pq/0010_smbios_16g_boundary.patch pc-bios/bios-pq/0010_smbios_16g_boundary.patch
--- pc-bios.orig/bios-pq/0010_smbios_16g_boundary.patch	1969-12-31 21:00:00.000000000 -0300
+++ pc-bios/bios-pq/0010_smbios_16g_boundary.patch	2009-01-19 23:18:46.000000000 -0200
@@ -0,0 +1,22 @@
+kvm: bios: fix smbios memory device length boundary condition
+   
+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>
+
+From: Bill Rieske <brieske@novell.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));
diff -Nur pc-bios.orig/bios-pq/series pc-bios/bios-pq/series
--- pc-bios.orig/bios-pq/series	2009-01-19 22:34:58.000000000 -0200
+++ pc-bios/bios-pq/series	2009-01-19 23:19:02.000000000 -0200
@@ -1 +1,10 @@
 0001_bx-qemu.patch
+0002_smbios_report_4g.patch
+0003_mptable_unconditional.patch
+0004_mtrr_up.patch
+0005_mtrr_smp.patch
+0006_mtrr_above_4g.patch
+0007_mtrr_above_4g_clean.patch
+0008_mtrr_default.patch
+0009_smbios_16gb.patch
+0010_smbios_16g_boundary.patch

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] Re: [PATCH] MTRR+SMBIOS Bochs patches
  2009-01-20  1:28 [Qemu-devel] [PATCH] MTRR+SMBIOS Bochs patches Marcelo Tosatti
@ 2009-01-20  2:06 ` Anthony Liguori
  2009-01-20 10:54   ` Carl-Daniel Hailfinger
  0 siblings, 1 reply; 3+ messages in thread
From: Anthony Liguori @ 2009-01-20  2:06 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: qemu-devel, Avi Kivity

Marcelo Tosatti wrote:
> Attached patch adds a series of patches against Bochs, from KVM tree: 
>   - SMBIOS updates
>   - MTRR support
>   - unconditional mptable
>
> Alex Williamson (4):
>      kvm: bios: extend MTRRs to above 4G
>      kvm: bios: cleanup/consolidate above 4G memory parsing
>      kvm: bios: update SMBIOS table to report memory above 4G
>      kvm: bios: switch MTRRs to cover only the PCI range and default to WB
>
> Avi Kivity (3):
>      kvm: bios: generate mptable unconditionally
>      kvm: bios: add mtrr support
>      kvm: bios: smp mtrr support
>
> Bill Rieske (2):
>      kvm: bios: resolve memory device roll over reporting issues with >32 guests
>      kvm: bios: fix smbios memory device length boundary condition
>
>   
Wow, awesome!

Can you send each patch as a member of a patch series so they can be 
reviewed individually?  Please CC bochs-devel.  I'll take care of 
putting them in the right place in SVN.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] MTRR+SMBIOS Bochs patches
  2009-01-20  2:06 ` [Qemu-devel] " Anthony Liguori
@ 2009-01-20 10:54   ` Carl-Daniel Hailfinger
  0 siblings, 0 replies; 3+ messages in thread
From: Carl-Daniel Hailfinger @ 2009-01-20 10:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marcelo Tosatti, Avi Kivity

On 20.01.2009 03:06, Anthony Liguori wrote:
> Marcelo Tosatti wrote:
>> Attached patch adds a series of patches against Bochs, from KVM tree:
>>   - SMBIOS updates
>>   - MTRR support
>>   - unconditional mptable
>>
>> Alex Williamson (4):
>>      kvm: bios: extend MTRRs to above 4G
>>      kvm: bios: cleanup/consolidate above 4G memory parsing
>>      kvm: bios: update SMBIOS table to report memory above 4G
>>      kvm: bios: switch MTRRs to cover only the PCI range and default
>> to WB
>>
>> Avi Kivity (3):
>>      kvm: bios: generate mptable unconditionally
>>      kvm: bios: add mtrr support
>>      kvm: bios: smp mtrr support
>>
>> Bill Rieske (2):
>>      kvm: bios: resolve memory device roll over reporting issues with
>> >32 guests
>>      kvm: bios: fix smbios memory device length boundary condition
>>
>>   
> Wow, awesome!
>
> Can you send each patch as a member of a patch series so they can be
> reviewed individually?  Please CC bochs-devel.  I'll take care of
> putting them in the right place in SVN.

All MTRR settings will be completely ignored by Qemu (writes will be
discarded, reads will be zero) unless you also apply my Qemu MTRR
support patch.

Subject: Re: [Qemu-devel] [PATCH] MTRR support on x86, part 1
Date: Thu, 11 Dec 2008 23:37:05 +0100

Should I resend that patch? It still applies to Qemu svn HEAD.

Regards,
Carl-Daniel

-- 
http://www.hailfinger.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-01-20 10:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-20  1:28 [Qemu-devel] [PATCH] MTRR+SMBIOS Bochs patches Marcelo Tosatti
2009-01-20  2:06 ` [Qemu-devel] " Anthony Liguori
2009-01-20 10:54   ` Carl-Daniel Hailfinger

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).