void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,

                        uint64_t mcg_status, uint64_t addr, uint64_t misc)

{

    uint64_t mcg_cap = cenv->mcg_cap;

    unsigned bank_num = mcg_cap & 0xff;

    uint64_t *banks = cenv->mce_banks;



    if (bank >= bank_num || !(status & MCI_STATUS_VAL))

        return;



    if (kvm_enabled()) {

        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);

        return;

    }



    







    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&

        cenv->mcg_ctl != ~(uint64_t)0)

        return;

    banks += 4 * bank;

    







    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)

        return;

    if (status & MCI_STATUS_UC) {

        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||

            !(cenv->cr[4] & CR4_MCE_MASK)) {

            fprintf(stderr, "injects mce exception while previous "

                    "one is in progress!\n");

            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");

            qemu_system_reset_request();

            return;

        }

        if (banks[1] & MCI_STATUS_VAL)

            status |= MCI_STATUS_OVER;

        banks[2] = addr;

        banks[3] = misc;

        cenv->mcg_status = mcg_status;

        banks[1] = status;

        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);

    } else if (!(banks[1] & MCI_STATUS_VAL)

               || !(banks[1] & MCI_STATUS_UC)) {

        if (banks[1] & MCI_STATUS_VAL)

            status |= MCI_STATUS_OVER;

        banks[2] = addr;

        banks[3] = misc;

        banks[1] = status;

    } else

        banks[1] |= MCI_STATUS_OVER;

}
