* [Qemu-devel] [patch 1/9] kvm: bios: update SMBIOS table to report memory above 4G
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 2/9] kvm: bios: generate mptable unconditionally Marcelo Tosatti
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity, Alex Williamson
[-- Attachment #1: 0002_smbios_report_4g.patch --]
[-- Type: text/plain, Size: 1217 bytes --]
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));
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 2/9] kvm: bios: generate mptable unconditionally
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 1/9] kvm: bios: update SMBIOS table to report memory above 4G Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 3/9] kvm: bios: add mtrr support Marcelo Tosatti
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity
[-- Attachment #1: 0003_mptable_unconditional.patch --]
[-- Type: text/plain, Size: 597 bytes --]
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 3/9] kvm: bios: add mtrr support
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 1/9] kvm: bios: update SMBIOS table to report memory above 4G Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 2/9] kvm: bios: generate mptable unconditionally Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 4/9] kvm: bios: smp " Marcelo Tosatti
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity
[-- Attachment #1: 0004_mtrr_up.patch --]
[-- Type: text/plain, Size: 3394 bytes --]
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();
}
/****************************************************/
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 4/9] kvm: bios: smp mtrr support
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (2 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 3/9] kvm: bios: add mtrr support Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 5/9] kvm: bios: extend MTRRs to above 4G Marcelo Tosatti
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity
[-- Attachment #1: 0005_mtrr_smp.patch --]
[-- Type: text/plain, Size: 3414 bytes --]
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 5/9] kvm: bios: extend MTRRs to above 4G
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (3 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 4/9] kvm: bios: smp " Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 6/9] kvm: bios: cleanup/consolidate above 4G memory parsing Marcelo Tosatti
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity, Alex Williamson
[-- Attachment #1: 0006_mtrr_above_4g.patch --]
[-- Type: text/plain, Size: 2036 bytes --]
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();
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 6/9] kvm: bios: cleanup/consolidate above 4G memory parsing
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (4 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 5/9] kvm: bios: extend MTRRs to above 4G Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 7/9] kvm: bios: switch MTRRs to cover only the PCI range and default to WB Marcelo Tosatti
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity, Alex Williamson
[-- Attachment #1: 0007_mtrr_above_4g_clean.patch --]
[-- Type: text/plain, Size: 2085 bytes --]
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();
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 7/9] kvm: bios: switch MTRRs to cover only the PCI range and default to WB
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (5 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 6/9] kvm: bios: cleanup/consolidate above 4G memory parsing Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 8/9] kvm: bios: resolve memory device roll over reporting issues with >32G guests Marcelo Tosatti
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Avi Kivity, Alex Williamson
[-- Attachment #1: 0008_mtrr_default.patch --]
[-- Type: text/plain, Size: 1814 bytes --]
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)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 8/9] kvm: bios: resolve memory device roll over reporting issues with >32G guests
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (6 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 7/9] kvm: bios: switch MTRRs to cover only the PCI range and default to WB Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-20 2:30 ` [Qemu-devel] [patch 9/9] kvm: bios: fix smbios memory device length boundary condition Marcelo Tosatti
2009-01-21 21:47 ` [Qemu-devel] Re: [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Anthony Liguori
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Bill Rieske, Avi Kivity
[-- Attachment #1: 0009_smbios_16gb.patch --]
[-- Type: text/plain, Size: 6388 bytes --]
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));
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [patch 9/9] kvm: bios: fix smbios memory device length boundary condition
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (7 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 8/9] kvm: bios: resolve memory device roll over reporting issues with >32G guests Marcelo Tosatti
@ 2009-01-20 2:30 ` Marcelo Tosatti
2009-01-21 21:47 ` [Qemu-devel] Re: [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Anthony Liguori
9 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2009-01-20 2:30 UTC (permalink / raw)
To: qemu-devel, bochs-developers; +Cc: Anthony Liguori, Bill Rieske, Avi Kivity
[-- Attachment #1: 0010_smbios_16g_boundary.patch --]
[-- Type: text/plain, Size: 837 bytes --]
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));
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] Re: [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates
2009-01-20 2:30 [Qemu-devel] [patch 0/9] Bochs BIOS MTRR support + SMBIOS updates Marcelo Tosatti
` (8 preceding siblings ...)
2009-01-20 2:30 ` [Qemu-devel] [patch 9/9] kvm: bios: fix smbios memory device length boundary condition Marcelo Tosatti
@ 2009-01-21 21:47 ` Anthony Liguori
9 siblings, 0 replies; 11+ messages in thread
From: Anthony Liguori @ 2009-01-21 21:47 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: bochs-developers, qemu-devel
Marcelo Tosatti wrote:
> MTRR support and SMBIOS updates from KVM tree:
>
Applied them all as one commit. Thanks.
Regards,
Anthony Liguori
> - 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
>
>
>
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread