Revision d5bfda33 target-i386/helper.c

b/target-i386/helper.c
1067 1067
        prev_debug_excp_handler(env);
1068 1068
}
1069 1069

  
1070
static void
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,
1073
                    int flags)
1070
typedef struct MCEInjectionParams {
1071
    Monitor *mon;
1072
    CPUState *env;
1073
    int bank;
1074
    uint64_t status;
1075
    uint64_t mcg_status;
1076
    uint64_t addr;
1077
    uint64_t misc;
1078
    int flags;
1079
} MCEInjectionParams;
1080

  
1081
static void do_inject_x86_mce(void *data)
1074 1082
{
1075
    uint64_t mcg_cap = cenv->mcg_cap;
1076
    uint64_t *banks = cenv->mce_banks + 4 * bank;
1083
    MCEInjectionParams *params = data;
1084
    CPUState *cenv = params->env;
1085
    uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1086

  
1087
    cpu_synchronize_state(cenv);
1077 1088

  
1078 1089
    /*
1079 1090
     * If there is an MCE exception being processed, ignore this SRAO MCE
1080 1091
     * unless unconditional injection was requested.
1081 1092
     */
1082
    if (!(flags & MCE_INJECT_UNCOND_AO) && !(status & MCI_STATUS_AR)
1093
    if (!(params->flags & MCE_INJECT_UNCOND_AO)
1094
        && !(params->status & MCI_STATUS_AR)
1083 1095
        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1084 1096
        return;
1085 1097
    }
1086
    if (status & MCI_STATUS_UC) {
1098

  
1099
    if (params->status & MCI_STATUS_UC) {
1087 1100
        /*
1088 1101
         * if MSR_MCG_CTL is not all 1s, the uncorrected error
1089 1102
         * reporting is disabled
1090 1103
         */
1091
        if ((mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1092
            monitor_printf(mon,
1104
        if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1105
            monitor_printf(params->mon,
1093 1106
                           "CPU %d: Uncorrected error reporting disabled\n",
1094 1107
                           cenv->cpu_index);
1095 1108
            return;
......
1100 1113
         * reporting is disabled for the bank
1101 1114
         */
1102 1115
        if (banks[0] != ~(uint64_t)0) {
1103
            monitor_printf(mon, "CPU %d: Uncorrected error reporting disabled "
1104
                           "for bank %d\n", cenv->cpu_index, bank);
1116
            monitor_printf(params->mon,
1117
                           "CPU %d: Uncorrected error reporting disabled for"
1118
                           " bank %d\n",
1119
                           cenv->cpu_index, params->bank);
1105 1120
            return;
1106 1121
        }
1107 1122

  
1108 1123
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1109 1124
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1110
            monitor_printf(mon, "CPU %d: Previous MCE still in progress, "
1111
                                "raising triple fault\n", cenv->cpu_index);
1125
            monitor_printf(params->mon,
1126
                           "CPU %d: Previous MCE still in progress, raising"
1127
                           " triple fault\n",
1128
                           cenv->cpu_index);
1112 1129
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1113 1130
            qemu_system_reset_request();
1114 1131
            return;
1115 1132
        }
1116 1133
        if (banks[1] & MCI_STATUS_VAL) {
1117
            status |= MCI_STATUS_OVER;
1134
            params->status |= MCI_STATUS_OVER;
1118 1135
        }
1119
        banks[2] = addr;
1120
        banks[3] = misc;
1121
        cenv->mcg_status = mcg_status;
1122
        banks[1] = status;
1136
        banks[2] = params->addr;
1137
        banks[3] = params->misc;
1138
        cenv->mcg_status = params->mcg_status;
1139
        banks[1] = params->status;
1123 1140
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1124 1141
    } else if (!(banks[1] & MCI_STATUS_VAL)
1125 1142
               || !(banks[1] & MCI_STATUS_UC)) {
1126 1143
        if (banks[1] & MCI_STATUS_VAL) {
1127
            status |= MCI_STATUS_OVER;
1144
            params->status |= MCI_STATUS_OVER;
1128 1145
        }
1129
        banks[2] = addr;
1130
        banks[3] = misc;
1131
        banks[1] = status;
1146
        banks[2] = params->addr;
1147
        banks[3] = params->misc;
1148
        banks[1] = params->status;
1132 1149
    } else {
1133 1150
        banks[1] |= MCI_STATUS_OVER;
1134 1151
    }
......
1138 1155
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
1139 1156
                        uint64_t misc, int flags)
1140 1157
{
1158
    MCEInjectionParams params = {
1159
        .mon = mon,
1160
        .env = cenv,
1161
        .bank = bank,
1162
        .status = status,
1163
        .mcg_status = mcg_status,
1164
        .addr = addr,
1165
        .misc = misc,
1166
        .flags = flags,
1167
    };
1141 1168
    unsigned bank_num = cenv->mcg_cap & 0xff;
1142 1169
    CPUState *env;
1143 1170
    int flag = 0;
......
1167 1194

  
1168 1195
        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
1169 1196
    } else {
1170
        qemu_inject_x86_mce(mon, cenv, bank, status, mcg_status, addr, misc,
1171
                            flags);
1197
        run_on_cpu(cenv, do_inject_x86_mce, &params);
1172 1198
        if (flags & MCE_INJECT_BROADCAST) {
1199
            params.bank = 1;
1200
            params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1201
            params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1202
            params.addr = 0;
1203
            params.misc = 0;
1173 1204
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
1174 1205
                if (cenv == env) {
1175 1206
                    continue;
1176 1207
                }
1177
                qemu_inject_x86_mce(mon, env, 1,
1178
                                    MCI_STATUS_VAL | MCI_STATUS_UC,
1179
                                    MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0,
1180
                                    flags);
1208
                params.env = env;
1209
                run_on_cpu(cenv, do_inject_x86_mce, &params);
1181 1210
            }
1182 1211
        }
1183 1212
    }

Also available in: Unified diff