Loading pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch 0 → 100644 +33 −0 Original line number Diff line number Diff line update SMBIOS table to report memory above 4G (Alex Williamson) Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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)); pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch 0 → 100644 +25 −0 Original line number Diff line number Diff line generate mptable unconditionally (Avi Kivity) VMware ESX requires an mptable even for uniprocessor guests. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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 pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch 0 → 100644 +120 −0 Original line number Diff line number Diff line add mtrr support (Avi Kivity) program mtrrs for cpu 0. Doesn't support >=4G at the moment. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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(); } /****************************************************/ pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch 0 → 100644 +126 −0 Original line number Diff line number Diff line smp mtrr support (Avi Kivity) Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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 pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch 0 → 100644 +62 −0 Original line number Diff line number Diff line 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 <alex.williamson@hp.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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(); } Loading
pc-bios/bios-pq/0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch 0 → 100644 +33 −0 Original line number Diff line number Diff line update SMBIOS table to report memory above 4G (Alex Williamson) Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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));
pc-bios/bios-pq/0003_kvm-bios-generate-mptable-unconditionally.patch 0 → 100644 +25 −0 Original line number Diff line number Diff line generate mptable unconditionally (Avi Kivity) VMware ESX requires an mptable even for uniprocessor guests. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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
pc-bios/bios-pq/0004_kvm-bios-add-mtrr-support.patch 0 → 100644 +120 −0 Original line number Diff line number Diff line add mtrr support (Avi Kivity) program mtrrs for cpu 0. Doesn't support >=4G at the moment. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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(); } /****************************************************/
pc-bios/bios-pq/0005_kvm-bios-smp-mtrr-support.patch 0 → 100644 +126 −0 Original line number Diff line number Diff line smp mtrr support (Avi Kivity) Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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
pc-bios/bios-pq/0006_kvm-bios-extend-mtrrs-to-above-4g.patch 0 → 100644 +62 −0 Original line number Diff line number Diff line 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 <alex.williamson@hp.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.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(); }