Skip to content

Commit

Permalink
KVM: x86: Enable CMCI capability by default and handle injected UCNA …
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
Jue Wang authored and Paolo Bonzini committed Jun 24, 2022
1 parent 281b527 commit aebc3ca
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
1 change: 1 addition & 0 deletions arch/x86/kvm/vmx/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
43 changes: 42 additions & 1 deletion arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -4901,6 +4901,42 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
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)
{
Expand All @@ -4910,14 +4946,19 @@ 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
*/
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
Expand Down

0 comments on commit aebc3ca

Please sign in to comment.