diff options
| author | Andre Przywara <andre.przywara@amd.com> | 2010-03-24 12:46:42 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2010-04-20 05:59:31 -0400 |
| commit | 114be429c8cd44e57f312af2bbd6734e5a185b0d (patch) | |
| tree | 97ff3b4ea1e6f0f17a3ebe1cdd57f3c0682a789e | |
| parent | d6a23895aa82353788a1cc5a1d9a1c963465463e (diff) | |
KVM: allow bit 10 to be cleared in MSR_IA32_MC4_CTL
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>
| -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 8f9b08d72c4d..9ad3d064c781 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -940,9 +940,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
| 940 | if (msr >= MSR_IA32_MC0_CTL && | 940 | if (msr >= MSR_IA32_MC0_CTL && |
| 941 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { | 941 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { |
| 942 | u32 offset = msr - MSR_IA32_MC0_CTL; | 942 | u32 offset = msr - MSR_IA32_MC0_CTL; |
| 943 | /* only 0 or all 1s can be written to IA32_MCi_CTL */ | 943 | /* only 0 or all 1s can be written to IA32_MCi_CTL |
| 944 | * some Linux kernels though clear bit 10 in bank 4 to | ||
| 945 | * workaround a BIOS/GART TBL issue on AMD K8s, ignore | ||
| 946 | * this to avoid an uncatched #GP in the guest | ||
| 947 | */ | ||
| 944 | if ((offset & 0x3) == 0 && | 948 | if ((offset & 0x3) == 0 && |
| 945 | data != 0 && data != ~(u64)0) | 949 | data != 0 && (data | (1 << 10)) != ~(u64)0) |
| 946 | return -1; | 950 | return -1; |
| 947 | vcpu->arch.mce_banks[offset] = data; | 951 | vcpu->arch.mce_banks[offset] = data; |
| 948 | break; | 952 | break; |
