aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@amd.com>2010-03-24 12:46:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-26 10:48:05 -0400
commitec861e75183fa0049917cbfa44d8a17e7ece7b4f (patch)
tree105a4ce0290e543473983fb95335935e02b16338 /arch
parent34ae17fafc868b82dbc3314a046d654feff43254 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/x86.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1b880f8720d2..cd3dc54e2fc4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -886,9 +886,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
886 if (msr >= MSR_IA32_MC0_CTL && 886 if (msr >= MSR_IA32_MC0_CTL &&
887 msr < MSR_IA32_MC0_CTL + 4 * bank_num) { 887 msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
888 u32 offset = msr - MSR_IA32_MC0_CTL; 888 u32 offset = msr - MSR_IA32_MC0_CTL;
889 /* only 0 or all 1s can be written to IA32_MCi_CTL */ 889 /* only 0 or all 1s can be written to IA32_MCi_CTL
890 * some Linux kernels though clear bit 10 in bank 4 to
891 * workaround a BIOS/GART TBL issue on AMD K8s, ignore
892 * this to avoid an uncatched #GP in the guest
893 */
890 if ((offset & 0x3) == 0 && 894 if ((offset & 0x3) == 0 &&
891 data != 0 && data != ~(u64)0) 895 data != 0 && (data | (1 << 10)) != ~(u64)0)
892 return -1; 896 return -1;
893 vcpu->arch.mce_banks[offset] = data; 897 vcpu->arch.mce_banks[offset] = data;
894 break; 898 break;