diff options
author | Andre Przywara <andre.przywara@amd.com> | 2010-03-24 17:46:42 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-26 07:41:37 -0700 |
commit | 6abddbe74fac81296e4d3cee3ba7327c27a96dde (patch) | |
tree | 4e7ddafd272199c79435ca8523c9fae0fcddee1b | |
parent | 31e104dc1fbd6e72d8d3e07c38bc77437b82d116 (diff) | |
download | linux-stable-6abddbe74fac81296e4d3cee3ba7327c27a96dde.tar.gz linux-stable-6abddbe74fac81296e4d3cee3ba7327c27a96dde.tar.bz2 linux-stable-6abddbe74fac81296e4d3cee3ba7327c27a96dde.zip |
KVM: allow bit 10 to be cleared in MSR_IA32_MC4_CTL
(Cherry-picked from commit 114be429c8cd44e57f312af2bbd6734e5a185b0d)
There is a quirk for AMD K8 CPUs in many Linux kernels (see
arch/x86/kernel/cpu/mcheck/mce.c:__mcheck_cpu_apply_quirks()) that
clears bit 10 in that MCE related MSR. KVM can only cope with all
zeros or all ones, so it will inject a #GP into the guest, which
will let it panic.
So lets add a quirk to the quirk and ignore this single cleared bit.
This fixes -cpu kvm64 on all machines and -cpu host on K8 machines
with some guest Linux kernels.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | arch/x86/kvm/x86.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 37d789b53673..759f88f4d238 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -799,9 +799,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) if (msr >= MSR_IA32_MC0_CTL && msr < MSR_IA32_MC0_CTL + 4 * bank_num) { u32 offset = msr - MSR_IA32_MC0_CTL; - /* only 0 or all 1s can be written to IA32_MCi_CTL */ + /* only 0 or all 1s can be written to IA32_MCi_CTL + * some Linux kernels though clear bit 10 in bank 4 to + * workaround a BIOS/GART TBL issue on AMD K8s, ignore + * this to avoid an uncatched #GP in the guest + */ if ((offset & 0x3) == 0 && - data != 0 && data != ~(u64)0) + data != 0 && (data | (1 << 10)) != ~(u64)0) return -1; vcpu->arch.mce_banks[offset] = data; break; |