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