28 |
28 |
#include "qemu-common.h"
|
29 |
29 |
#include "kvm.h"
|
30 |
30 |
#include "kvm_x86.h"
|
|
31 |
#ifndef CONFIG_USER_ONLY
|
|
32 |
#include "sysemu.h"
|
|
33 |
#endif
|
31 |
34 |
|
32 |
35 |
//#define DEBUG_MMU
|
33 |
36 |
|
... | ... | |
1063 |
1066 |
prev_debug_excp_handler(env);
|
1064 |
1067 |
}
|
1065 |
1068 |
|
1066 |
|
/* This should come from sysemu.h - if we could include it here... */
|
1067 |
|
void qemu_system_reset_request(void);
|
1068 |
|
|
1069 |
|
static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
1070 |
|
uint64_t mcg_status, uint64_t addr, uint64_t misc)
|
|
1069 |
static void
|
|
1070 |
qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
|
1071 |
uint64_t mcg_status, uint64_t addr, uint64_t misc)
|
1071 |
1072 |
{
|
1072 |
1073 |
uint64_t mcg_cap = cenv->mcg_cap;
|
1073 |
1074 |
uint64_t *banks = cenv->mce_banks;
|
... | ... | |
1077 |
1078 |
* reporting is disabled
|
1078 |
1079 |
*/
|
1079 |
1080 |
if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
|
1080 |
|
cenv->mcg_ctl != ~(uint64_t)0)
|
|
1081 |
cenv->mcg_ctl != ~(uint64_t)0) {
|
1081 |
1082 |
return;
|
|
1083 |
}
|
1082 |
1084 |
banks += 4 * bank;
|
1083 |
1085 |
/*
|
1084 |
1086 |
* if MSR_MCi_CTL is not all 1s, the uncorrected error
|
1085 |
1087 |
* reporting is disabled for the bank
|
1086 |
1088 |
*/
|
1087 |
|
if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
|
|
1089 |
if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0) {
|
1088 |
1090 |
return;
|
|
1091 |
}
|
1089 |
1092 |
if (status & MCI_STATUS_UC) {
|
1090 |
1093 |
if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
|
1091 |
1094 |
!(cenv->cr[4] & CR4_MCE_MASK)) {
|
... | ... | |
1095 |
1098 |
qemu_system_reset_request();
|
1096 |
1099 |
return;
|
1097 |
1100 |
}
|
1098 |
|
if (banks[1] & MCI_STATUS_VAL)
|
|
1101 |
if (banks[1] & MCI_STATUS_VAL) {
|
1099 |
1102 |
status |= MCI_STATUS_OVER;
|
|
1103 |
}
|
1100 |
1104 |
banks[2] = addr;
|
1101 |
1105 |
banks[3] = misc;
|
1102 |
1106 |
cenv->mcg_status = mcg_status;
|
... | ... | |
1104 |
1108 |
cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
|
1105 |
1109 |
} else if (!(banks[1] & MCI_STATUS_VAL)
|
1106 |
1110 |
|| !(banks[1] & MCI_STATUS_UC)) {
|
1107 |
|
if (banks[1] & MCI_STATUS_VAL)
|
|
1111 |
if (banks[1] & MCI_STATUS_VAL) {
|
1108 |
1112 |
status |= MCI_STATUS_OVER;
|
|
1113 |
}
|
1109 |
1114 |
banks[2] = addr;
|
1110 |
1115 |
banks[3] = misc;
|
1111 |
1116 |
banks[1] = status;
|
1112 |
|
} else
|
|
1117 |
} else {
|
1113 |
1118 |
banks[1] |= MCI_STATUS_OVER;
|
|
1119 |
}
|
1114 |
1120 |
}
|
1115 |
1121 |
|
1116 |
|
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
|
1122 |
void cpu_x86_inject_mce(CPUState *cenv, int bank, uint64_t status,
|
1117 |
1123 |
uint64_t mcg_status, uint64_t addr, uint64_t misc,
|
1118 |
1124 |
int broadcast)
|
1119 |
1125 |
{
|
... | ... | |
1155 |
1161 |
|
1156 |
1162 |
static void mce_init(CPUX86State *cenv)
|
1157 |
1163 |
{
|
1158 |
|
unsigned int bank, bank_num;
|
|
1164 |
unsigned int bank;
|
1159 |
1165 |
|
1160 |
|
if (((cenv->cpuid_version >> 8)&0xf) >= 6
|
1161 |
|
&& (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
|
|
1166 |
if (((cenv->cpuid_version >> 8) & 0xf) >= 6
|
|
1167 |
&& (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
|
|
1168 |
(CPUID_MCE | CPUID_MCA)) {
|
1162 |
1169 |
cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
|
1163 |
1170 |
cenv->mcg_ctl = ~(uint64_t)0;
|
1164 |
|
bank_num = MCE_BANKS_DEF;
|
1165 |
|
for (bank = 0; bank < bank_num; bank++)
|
1166 |
|
cenv->mce_banks[bank*4] = ~(uint64_t)0;
|
|
1171 |
for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
|
|
1172 |
cenv->mce_banks[bank * 4] = ~(uint64_t)0;
|
|
1173 |
}
|
1167 |
1174 |
}
|
1168 |
1175 |
}
|
1169 |
1176 |
|