mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07: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:
@@ -1663,15 +1663,31 @@ if test "$kvm" != "no" ; then
|
||||
#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
|
||||
#error Invalid KVM version
|
||||
#endif
|
||||
#if !defined(KVM_CAP_USER_MEMORY)
|
||||
#error Missing KVM capability KVM_CAP_USER_MEMORY
|
||||
#endif
|
||||
#if !defined(KVM_CAP_SET_TSS_ADDR)
|
||||
#error Missing KVM capability KVM_CAP_SET_TSS_ADDR
|
||||
#endif
|
||||
#if !defined(KVM_CAP_DESTROY_MEMORY_REGION_WORKS)
|
||||
#error Missing KVM capability KVM_CAP_DESTROY_MEMORY_REGION_WORKS
|
||||
EOF
|
||||
must_have_caps="KVM_CAP_USER_MEMORY \
|
||||
KVM_CAP_DESTROY_MEMORY_REGION_WORKS \
|
||||
KVM_CAP_COALESCED_MMIO \
|
||||
KVM_CAP_SYNC_MMU \
|
||||
"
|
||||
if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then
|
||||
must_have_caps="$caps \
|
||||
KVM_CAP_SET_TSS_ADDR \
|
||||
KVM_CAP_EXT_CPUID \
|
||||
KVM_CAP_CLOCKSOURCE \
|
||||
KVM_CAP_NOP_IO_DELAY \
|
||||
KVM_CAP_PV_MMU \
|
||||
KVM_CAP_MP_STATE \
|
||||
KVM_CAP_USER_NMI \
|
||||
"
|
||||
fi
|
||||
for c in $must_have_caps ; do
|
||||
cat >> $TMPC <<EOF
|
||||
#if !defined($c)
|
||||
#error Missing KVM capability $c
|
||||
#endif
|
||||
EOF
|
||||
done
|
||||
cat >> $TMPC <<EOF
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
if test "$kerneldir" != "" ; then
|
||||
@@ -1706,8 +1722,8 @@ EOF
|
||||
| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
|
||||
if test "$kvmerr" != "" ; then
|
||||
echo -e "${kvmerr}\n\
|
||||
NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
|
||||
recent kvm-kmod from http://sourceforge.net/projects/kvm."
|
||||
NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
|
||||
recent kvm-kmod from http://sourceforge.net/projects/kvm."
|
||||
fi
|
||||
fi
|
||||
feature_not_found "kvm"
|
||||
|
||||
@@ -765,6 +765,8 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
|
||||
CPUState *cpu_copy(CPUState *env);
|
||||
CPUState *qemu_get_cpu(int cpu);
|
||||
|
||||
#define CPU_DUMP_CODE 0x00010000
|
||||
|
||||
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
|
||||
int flags);
|
||||
void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
|
||||
@@ -964,6 +966,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
|
||||
uint8_t *buf, int len, int is_write);
|
||||
|
||||
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
|
||||
uint64_t mcg_status, uint64_t addr, uint64_t misc);
|
||||
uint64_t mcg_status, uint64_t addr, uint64_t misc,
|
||||
int broadcast);
|
||||
|
||||
#endif /* CPU_ALL_H */
|
||||
|
||||
@@ -735,9 +735,7 @@ static sigset_t block_io_signals(void)
|
||||
void qemu_mutex_lock_iothread(void)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
qemu_mutex_lock(&qemu_fair_mutex);
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
qemu_mutex_unlock(&qemu_fair_mutex);
|
||||
} else {
|
||||
qemu_mutex_lock(&qemu_fair_mutex);
|
||||
if (qemu_mutex_trylock(&qemu_global_mutex)) {
|
||||
|
||||
+3
-3
@@ -1152,9 +1152,9 @@ ETEXI
|
||||
|
||||
{
|
||||
.name = "mce",
|
||||
.args_type = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
|
||||
.params = "cpu bank status mcgstatus addr misc",
|
||||
.help = "inject a MCE on the given CPU",
|
||||
.args_type = "broadcast:-b,cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
|
||||
.params = "[-b] cpu bank status mcgstatus addr misc",
|
||||
.help = "inject a MCE on the given CPU [and broadcast to other CPUs with -b option]",
|
||||
.mhandler.cmd = do_inject_mce,
|
||||
},
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_init(int smp_cpus)
|
||||
int kvm_init(void)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,17 @@ extern int kvm_allowed;
|
||||
|
||||
struct kvm_run;
|
||||
|
||||
typedef struct KVMCapabilityInfo {
|
||||
const char *name;
|
||||
int value;
|
||||
} KVMCapabilityInfo;
|
||||
|
||||
#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
|
||||
#define KVM_CAP_LAST_INFO { NULL, 0 }
|
||||
|
||||
/* external API */
|
||||
|
||||
int kvm_init(int smp_cpus);
|
||||
int kvm_init(void);
|
||||
|
||||
int kvm_has_sync_mmu(void);
|
||||
int kvm_has_vcpu_events(void);
|
||||
@@ -86,6 +94,8 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...);
|
||||
|
||||
/* Arch specific hooks */
|
||||
|
||||
extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
|
||||
|
||||
int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
|
||||
|
||||
int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run);
|
||||
@@ -105,7 +115,7 @@ int kvm_arch_get_registers(CPUState *env);
|
||||
|
||||
int kvm_arch_put_registers(CPUState *env, int level);
|
||||
|
||||
int kvm_arch_init(KVMState *s, int smp_cpus);
|
||||
int kvm_arch_init(KVMState *s);
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *env);
|
||||
|
||||
|
||||
@@ -2709,12 +2709,15 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
|
||||
uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
|
||||
uint64_t addr = qdict_get_int(qdict, "addr");
|
||||
uint64_t misc = qdict_get_int(qdict, "misc");
|
||||
int broadcast = qdict_get_try_bool(qdict, "broadcast", 0);
|
||||
|
||||
for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
|
||||
for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
|
||||
if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
|
||||
cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
|
||||
cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc,
|
||||
broadcast);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+7
-2
@@ -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,
|
||||
|
||||
+2
-3
@@ -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];
|
||||
|
||||
+87
-10
@@ -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)
|
||||
|
||||
+423
-328
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
|
||||
|
||||
+9
-1
@@ -37,6 +37,10 @@
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
|
||||
static int cap_interrupt_unset = false;
|
||||
static int cap_interrupt_level = false;
|
||||
|
||||
@@ -56,7 +60,7 @@ static void kvm_kick_env(void *env)
|
||||
qemu_cpu_kick(env);
|
||||
}
|
||||
|
||||
int kvm_arch_init(KVMState *s, int smp_cpus)
|
||||
int kvm_arch_init(KVMState *s)
|
||||
{
|
||||
#ifdef KVM_CAP_PPC_UNSET_IRQ
|
||||
cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
|
||||
@@ -307,6 +311,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
|
||||
dprintf("handle halt\n");
|
||||
ret = kvmppc_handle_halt(env);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+5
-1
@@ -70,7 +70,11 @@
|
||||
#define SCLP_CMDW_READ_SCP_INFO 0x00020001
|
||||
#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
|
||||
|
||||
int kvm_arch_init(KVMState *s, int smp_cpus)
|
||||
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
|
||||
int kvm_arch_init(KVMState *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user