Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ffd986c authored by Wanpeng Li's avatar Wanpeng Li Committed by Radim Krčmář
Browse files

KVM: X86: #GP when guest attempts to write MCi_STATUS register w/o 0



Both Intel SDM and AMD APM mentioned that MCi_STATUS, when the register is
implemented, this register can be cleared by explicitly writing 0s to this
register. Writing 1s to this register will cause a general-protection
exception.

The mce is emulated in qemu, so just the guest attempts to write 1 to this
register should cause a #GP, this patch does it.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Jim Mattson <jmattson@google.com>
Signed-off-by: default avatarWanpeng Li <wanpeng.li@hotmail.com>
Reviewed-by: default avatarJim Mattson <jmattson@google.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent 61f1dd90
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -2006,10 +2006,12 @@ static void kvmclock_sync_fn(struct work_struct *work)
					KVMCLOCK_SYNC_PERIOD);
					KVMCLOCK_SYNC_PERIOD);
}
}


static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
{
	u64 mcg_cap = vcpu->arch.mcg_cap;
	u64 mcg_cap = vcpu->arch.mcg_cap;
	unsigned bank_num = mcg_cap & 0xff;
	unsigned bank_num = mcg_cap & 0xff;
	u32 msr = msr_info->index;
	u64 data = msr_info->data;


	switch (msr) {
	switch (msr) {
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MCG_STATUS:
@@ -2034,6 +2036,9 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
			if ((offset & 0x3) == 0 &&
			if ((offset & 0x3) == 0 &&
			    data != 0 && (data | (1 << 10)) != ~(u64)0)
			    data != 0 && (data | (1 << 10)) != ~(u64)0)
				return -1;
				return -1;
			if (!msr_info->host_initiated &&
				(offset & 0x3) == 1 && data != 0)
				return -1;
			vcpu->arch.mce_banks[offset] = data;
			vcpu->arch.mce_banks[offset] = data;
			break;
			break;
		}
		}
@@ -2283,7 +2288,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
	case MSR_IA32_MCG_CTL:
	case MSR_IA32_MCG_CTL:
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1:
	case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1:
		return set_msr_mce(vcpu, msr, data);
		return set_msr_mce(vcpu, msr_info);


	case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
	case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
	case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR1:
	case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR1: