27 |
27 |
#include "hw/pc.h"
|
28 |
28 |
#include "hw/apic.h"
|
29 |
29 |
#include "ioport.h"
|
|
30 |
#include "kvm_x86.h"
|
30 |
31 |
|
31 |
32 |
#ifdef CONFIG_KVM_PARA
|
32 |
33 |
#include <linux/kvm_para.h>
|
... | ... | |
167 |
168 |
}
|
168 |
169 |
#endif
|
169 |
170 |
|
|
171 |
#ifdef KVM_CAP_MCE
|
|
172 |
static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
|
|
173 |
int *max_banks)
|
|
174 |
{
|
|
175 |
int r;
|
|
176 |
|
|
177 |
r = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_MCE);
|
|
178 |
if (r > 0) {
|
|
179 |
*max_banks = r;
|
|
180 |
return kvm_ioctl(s, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
|
|
181 |
}
|
|
182 |
return -ENOSYS;
|
|
183 |
}
|
|
184 |
|
|
185 |
static int kvm_setup_mce(CPUState *env, uint64_t *mcg_cap)
|
|
186 |
{
|
|
187 |
return kvm_vcpu_ioctl(env, KVM_X86_SETUP_MCE, mcg_cap);
|
|
188 |
}
|
|
189 |
|
|
190 |
static int kvm_set_mce(CPUState *env, struct kvm_x86_mce *m)
|
|
191 |
{
|
|
192 |
return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, m);
|
|
193 |
}
|
|
194 |
|
|
195 |
struct kvm_x86_mce_data
|
|
196 |
{
|
|
197 |
CPUState *env;
|
|
198 |
struct kvm_x86_mce *mce;
|
|
199 |
};
|
|
200 |
|
|
201 |
static void kvm_do_inject_x86_mce(void *_data)
|
|
202 |
{
|
|
203 |
struct kvm_x86_mce_data *data = _data;
|
|
204 |
int r;
|
|
205 |
|
|
206 |
r = kvm_set_mce(data->env, data->mce);
|
|
207 |
if (r < 0)
|
|
208 |
perror("kvm_set_mce FAILED");
|
|
209 |
}
|
|
210 |
#endif
|
|
211 |
|
|
212 |
void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
|
213 |
uint64_t mcg_status, uint64_t addr, uint64_t misc)
|
|
214 |
{
|
|
215 |
#ifdef KVM_CAP_MCE
|
|
216 |
struct kvm_x86_mce mce = {
|
|
217 |
.bank = bank,
|
|
218 |
.status = status,
|
|
219 |
.mcg_status = mcg_status,
|
|
220 |
.addr = addr,
|
|
221 |
.misc = misc,
|
|
222 |
};
|
|
223 |
struct kvm_x86_mce_data data = {
|
|
224 |
.env = cenv,
|
|
225 |
.mce = &mce,
|
|
226 |
};
|
|
227 |
|
|
228 |
run_on_cpu(cenv, kvm_do_inject_x86_mce, &data);
|
|
229 |
#endif
|
|
230 |
}
|
|
231 |
|
170 |
232 |
int kvm_arch_init_vcpu(CPUState *env)
|
171 |
233 |
{
|
172 |
234 |
struct {
|
... | ... | |
277 |
339 |
|
278 |
340 |
cpuid_data.cpuid.nent = cpuid_i;
|
279 |
341 |
|
|
342 |
#ifdef KVM_CAP_MCE
|
|
343 |
if (((env->cpuid_version >> 8)&0xF) >= 6
|
|
344 |
&& (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)
|
|
345 |
&& kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) {
|
|
346 |
uint64_t mcg_cap;
|
|
347 |
int banks;
|
|
348 |
|
|
349 |
if (kvm_get_mce_cap_supported(env->kvm_state, &mcg_cap, &banks))
|
|
350 |
perror("kvm_get_mce_cap_supported FAILED");
|
|
351 |
else {
|
|
352 |
if (banks > MCE_BANKS_DEF)
|
|
353 |
banks = MCE_BANKS_DEF;
|
|
354 |
mcg_cap &= MCE_CAP_DEF;
|
|
355 |
mcg_cap |= banks;
|
|
356 |
if (kvm_setup_mce(env, &mcg_cap))
|
|
357 |
perror("kvm_setup_mce FAILED");
|
|
358 |
else
|
|
359 |
env->mcg_cap = mcg_cap;
|
|
360 |
}
|
|
361 |
}
|
|
362 |
#endif
|
|
363 |
|
280 |
364 |
return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
|
281 |
365 |
}
|
282 |
366 |
|