KVM: x86: Enable CMCI capability by default and handle injected UCNA errors
This patch enables MCG_CMCI_P by default in kvm_mce_cap_supported. It reuses ioctl KVM_X86_SET_MCE to implement injection of UnCorrectable No Action required (UCNA) errors, signaled via Corrected Machine Check Interrupt (CMCI). Neither of the CMCI and UCNA emulations depends on hardware. Signed-off-by: Jue Wang <juew@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20220610171134.772566-8-juew@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
281b52780b
Коммит
aebc3ca190
|
@ -8299,6 +8299,7 @@ static __init int hardware_setup(void)
|
|||
}
|
||||
|
||||
kvm_caps.supported_mce_cap |= MCG_LMCE_P;
|
||||
kvm_caps.supported_mce_cap |= MCG_CMCI_P;
|
||||
|
||||
if (pt_mode != PT_MODE_SYSTEM && pt_mode != PT_MODE_HOST_GUEST)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -4901,6 +4901,42 @@ out:
|
|||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate this is an UCNA (uncorrectable no action) error by checking the
|
||||
* MCG_STATUS and MCi_STATUS registers:
|
||||
* - none of the bits for Machine Check Exceptions are set
|
||||
* - both the VAL (valid) and UC (uncorrectable) bits are set
|
||||
* MCI_STATUS_PCC - Processor Context Corrupted
|
||||
* MCI_STATUS_S - Signaled as a Machine Check Exception
|
||||
* MCI_STATUS_AR - Software recoverable Action Required
|
||||
*/
|
||||
static bool is_ucna(struct kvm_x86_mce *mce)
|
||||
{
|
||||
return !mce->mcg_status &&
|
||||
!(mce->status & (MCI_STATUS_PCC | MCI_STATUS_S | MCI_STATUS_AR)) &&
|
||||
(mce->status & MCI_STATUS_VAL) &&
|
||||
(mce->status & MCI_STATUS_UC);
|
||||
}
|
||||
|
||||
static int kvm_vcpu_x86_set_ucna(struct kvm_vcpu *vcpu, struct kvm_x86_mce *mce, u64* banks)
|
||||
{
|
||||
u64 mcg_cap = vcpu->arch.mcg_cap;
|
||||
|
||||
banks[1] = mce->status;
|
||||
banks[2] = mce->addr;
|
||||
banks[3] = mce->misc;
|
||||
vcpu->arch.mcg_status = mce->mcg_status;
|
||||
|
||||
if (!(mcg_cap & MCG_CMCI_P) ||
|
||||
!(vcpu->arch.mci_ctl2_banks[mce->bank] & MCI_CTL2_CMCI_EN))
|
||||
return 0;
|
||||
|
||||
if (lapic_in_kernel(vcpu))
|
||||
kvm_apic_local_deliver(vcpu->arch.apic, APIC_LVTCMCI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
|
||||
struct kvm_x86_mce *mce)
|
||||
{
|
||||
|
@ -4910,6 +4946,12 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
|
|||
|
||||
if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL))
|
||||
return -EINVAL;
|
||||
|
||||
banks += array_index_nospec(4 * mce->bank, 4 * bank_num);
|
||||
|
||||
if (is_ucna(mce))
|
||||
return kvm_vcpu_x86_set_ucna(vcpu, mce, banks);
|
||||
|
||||
/*
|
||||
* if IA32_MCG_CTL is not all 1s, the uncorrected error
|
||||
* reporting is disabled
|
||||
|
@ -4917,7 +4959,6 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
|
|||
if ((mce->status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
|
||||
vcpu->arch.mcg_ctl != ~(u64)0)
|
||||
return 0;
|
||||
banks += 4 * mce->bank;
|
||||
/*
|
||||
* if IA32_MCi_CTL is not all 1s, the uncorrected error
|
||||
* reporting is disabled for the bank
|
||||
|
|
Загрузка…
Ссылка в новой задаче