mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
Merge remote branch 'qemu-kvm/uq/master' into staging
aliguori: fix build with !defined(KVM_CAP_ASYNC_PF) Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
b3a98367ee
16 changed files with 717 additions and 489 deletions
|
@ -699,6 +699,10 @@ typedef struct CPUX86State {
|
|||
uint32_t smbase;
|
||||
int old_exception; /* exception in flight */
|
||||
|
||||
/* KVM states, automatically cleared on reset */
|
||||
uint8_t nmi_injected;
|
||||
uint8_t nmi_pending;
|
||||
|
||||
CPU_COMMON
|
||||
|
||||
/* processor features (e.g. for CPUID insn) */
|
||||
|
@ -726,8 +730,6 @@ typedef struct CPUX86State {
|
|||
int32_t exception_injected;
|
||||
int32_t interrupt_injected;
|
||||
uint8_t soft_interrupt;
|
||||
uint8_t nmi_injected;
|
||||
uint8_t nmi_pending;
|
||||
uint8_t has_error_code;
|
||||
uint32_t sipi_vector;
|
||||
uint32_t cpuid_kvm_features;
|
||||
|
@ -760,6 +762,7 @@ int cpu_x86_exec(CPUX86State *s);
|
|||
void cpu_x86_close(CPUX86State *s);
|
||||
void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg);
|
||||
void x86_cpudef_setup(void);
|
||||
int cpu_x86_support_mca_broadcast(CPUState *env);
|
||||
|
||||
int cpu_get_pic_interrupt(CPUX86State *s);
|
||||
/* MSDOS compatibility mode FPU exception support */
|
||||
|
@ -873,6 +876,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|||
uint32_t *ecx, uint32_t *edx);
|
||||
int cpu_x86_register (CPUX86State *env, const char *cpu_model);
|
||||
void cpu_clear_apic_feature(CPUX86State *env);
|
||||
void host_cpuid(uint32_t function, uint32_t count,
|
||||
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
|
||||
|
||||
/* helper.c */
|
||||
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
|
||||
|
|
|
@ -103,9 +103,8 @@ typedef struct model_features_t {
|
|||
int check_cpuid = 0;
|
||||
int enforce_cpuid = 0;
|
||||
|
||||
static void host_cpuid(uint32_t function, uint32_t count,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
void host_cpuid(uint32_t function, uint32_t count,
|
||||
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
#if defined(CONFIG_KVM)
|
||||
uint32_t vec[4];
|
||||
|
|
|
@ -110,6 +110,32 @@ void cpu_x86_close(CPUX86State *env)
|
|||
qemu_free(env);
|
||||
}
|
||||
|
||||
static void cpu_x86_version(CPUState *env, int *family, int *model)
|
||||
{
|
||||
int cpuver = env->cpuid_version;
|
||||
|
||||
if (family == NULL || model == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
*family = (cpuver >> 8) & 0x0f;
|
||||
*model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
|
||||
}
|
||||
|
||||
/* Broadcast MCA signal for processor version 06H_EH and above */
|
||||
int cpu_x86_support_mca_broadcast(CPUState *env)
|
||||
{
|
||||
int family = 0;
|
||||
int model = 0;
|
||||
|
||||
cpu_x86_version(env, &family, &model);
|
||||
if ((family == 6 && model >= 14) || family > 6) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* x86 debug */
|
||||
|
||||
|
@ -223,6 +249,9 @@ done:
|
|||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
#define DUMP_CODE_BYTES_TOTAL 50
|
||||
#define DUMP_CODE_BYTES_BACKWARD 20
|
||||
|
||||
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
|
||||
int flags)
|
||||
{
|
||||
|
@ -408,6 +437,24 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
|
|||
cpu_fprintf(f, " ");
|
||||
}
|
||||
}
|
||||
if (flags & CPU_DUMP_CODE) {
|
||||
target_ulong base = env->segs[R_CS].base + env->eip;
|
||||
target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
|
||||
uint8_t code;
|
||||
char codestr[3];
|
||||
|
||||
cpu_fprintf(f, "Code=");
|
||||
for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
|
||||
if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
|
||||
snprintf(codestr, sizeof(codestr), "%02x", code);
|
||||
} else {
|
||||
snprintf(codestr, sizeof(codestr), "??");
|
||||
}
|
||||
cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
|
||||
i == offs ? "<" : "", codestr, i == offs ? ">" : "");
|
||||
}
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
@ -1021,21 +1068,12 @@ static void breakpoint_handler(CPUState *env)
|
|||
/* This should come from sysemu.h - if we could include it here... */
|
||||
void qemu_system_reset_request(void);
|
||||
|
||||
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
||||
static void qemu_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, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* if MSR_MCG_CTL is not all 1s, the uncorrected error
|
||||
* reporting is disabled
|
||||
|
@ -1076,6 +1114,45 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
|||
} else
|
||||
banks[1] |= MCI_STATUS_OVER;
|
||||
}
|
||||
|
||||
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
||||
uint64_t mcg_status, uint64_t addr, uint64_t misc,
|
||||
int broadcast)
|
||||
{
|
||||
unsigned bank_num = cenv->mcg_cap & 0xff;
|
||||
CPUState *env;
|
||||
int flag = 0;
|
||||
|
||||
if (bank >= bank_num || !(status & MCI_STATUS_VAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (broadcast) {
|
||||
if (!cpu_x86_support_mca_broadcast(cenv)) {
|
||||
fprintf(stderr, "Current CPU does not support broadcast\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (kvm_enabled()) {
|
||||
if (broadcast) {
|
||||
flag |= MCE_BROADCAST;
|
||||
}
|
||||
|
||||
kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
|
||||
} else {
|
||||
qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
|
||||
if (broadcast) {
|
||||
for (env = first_cpu; env != NULL; env = env->next_cpu) {
|
||||
if (cenv == env) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qemu_inject_x86_mce(env, 1, 0xa000000000000000, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
static void mce_init(CPUX86State *cenv)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,8 +15,11 @@
|
|||
#ifndef __KVM_X86_H__
|
||||
#define __KVM_X86_H__
|
||||
|
||||
#define ABORT_ON_ERROR 0x01
|
||||
#define MCE_BROADCAST 0x02
|
||||
|
||||
void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
||||
uint64_t mcg_status, uint64_t addr, uint64_t misc,
|
||||
int abort_on_error);
|
||||
int flag);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue