Revision 747461c7

b/monitor.c
2709 2709
    uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
2710 2710
    uint64_t addr = qdict_get_int(qdict, "addr");
2711 2711
    uint64_t misc = qdict_get_int(qdict, "misc");
2712
    int broadcast = qdict_get_try_bool(qdict, "broadcast", 0);
2712
    int flags = MCE_INJECT_UNCOND_AO;
2713 2713

  
2714
    if (qdict_get_try_bool(qdict, "broadcast", 0)) {
2715
        flags |= MCE_INJECT_BROADCAST;
2716
    }
2714 2717
    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
2715 2718
        if (cenv->cpu_index == cpu_index) {
2716 2719
            cpu_x86_inject_mce(mon, cenv, bank, status, mcg_status, addr, misc,
2717
                               broadcast);
2720
                               flags);
2718 2721
            break;
2719 2722
        }
2720 2723
    }
b/target-i386/cpu.h
987 987
void do_cpu_init(CPUState *env);
988 988
void do_cpu_sipi(CPUState *env);
989 989

  
990
#define MCE_INJECT_BROADCAST    1
991
#define MCE_INJECT_UNCOND_AO    2
992

  
990 993
void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
991 994
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
992
                        uint64_t misc, int broadcast);
995
                        uint64_t misc, int flags);
993 996

  
994 997
#endif /* CPU_I386_H */
b/target-i386/helper.c
1069 1069

  
1070 1070
static void
1071 1071
qemu_inject_x86_mce(Monitor *mon, CPUState *cenv, int bank, uint64_t status,
1072
                    uint64_t mcg_status, uint64_t addr, uint64_t misc)
1072
                    uint64_t mcg_status, uint64_t addr, uint64_t misc,
1073
                    int flags)
1073 1074
{
1074 1075
    uint64_t mcg_cap = cenv->mcg_cap;
1075 1076
    uint64_t *banks = cenv->mce_banks + 4 * bank;
1076 1077

  
1078
    /*
1079
     * If there is an MCE exception being processed, ignore this SRAO MCE
1080
     * unless unconditional injection was requested.
1081
     */
1082
    if (!(flags & MCE_INJECT_UNCOND_AO) && !(status & MCI_STATUS_AR)
1083
        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1084
        return;
1085
    }
1077 1086
    if (status & MCI_STATUS_UC) {
1078 1087
        /*
1079 1088
         * if MSR_MCG_CTL is not all 1s, the uncorrected error
......
1127 1136

  
1128 1137
void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1129 1138
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
1130
                        uint64_t misc, int broadcast)
1139
                        uint64_t misc, int flags)
1131 1140
{
1132 1141
    unsigned bank_num = cenv->mcg_cap & 0xff;
1133 1142
    CPUState *env;
......
1145 1154
        monitor_printf(mon, "Invalid MCE status code\n");
1146 1155
        return;
1147 1156
    }
1148
    if (broadcast && !cpu_x86_support_mca_broadcast(cenv)) {
1157
    if ((flags & MCE_INJECT_BROADCAST)
1158
        && !cpu_x86_support_mca_broadcast(cenv)) {
1149 1159
        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1150 1160
        return;
1151 1161
    }
1152 1162

  
1153 1163
    if (kvm_enabled()) {
1154
        if (broadcast) {
1164
        if (flags & MCE_INJECT_BROADCAST) {
1155 1165
            flag |= MCE_BROADCAST;
1156 1166
        }
1157 1167

  
1158 1168
        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
1159 1169
    } else {
1160
        qemu_inject_x86_mce(mon, cenv, bank, status, mcg_status, addr, misc);
1161
        if (broadcast) {
1170
        qemu_inject_x86_mce(mon, cenv, bank, status, mcg_status, addr, misc,
1171
                            flags);
1172
        if (flags & MCE_INJECT_BROADCAST) {
1162 1173
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
1163 1174
                if (cenv == env) {
1164 1175
                    continue;
1165 1176
                }
1166 1177
                qemu_inject_x86_mce(mon, env, 1,
1167 1178
                                    MCI_STATUS_VAL | MCI_STATUS_UC,
1168
                                    MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0);
1179
                                    MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0,
1180
                                    flags);
1169 1181
            }
1170 1182
        }
1171 1183
    }

Also available in: Unified diff