summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-12-10 14:08:22 +0200
committerAvi Kivity <avi@redhat.com>2009-12-10 14:08:22 +0200
commit1eab98bb5d1d9ad036f2acbe323642dd6c05492e (patch)
treec8260feee6ae597e8ee463c44201b663a975ed5c /target-i386
parentFix mismerge in cpu_post_load (diff)
parentInitialize apic before vcpu main loop (diff)
downloadqemu-kvm-1eab98bb5d1d9ad036f2acbe323642dd6c05492e.tar.gz
qemu-kvm-1eab98bb5d1d9ad036f2acbe323642dd6c05492e.tar.bz2
qemu-kvm-1eab98bb5d1d9ad036f2acbe323642dd6c05492e.zip
Merge branch 'upstream-merge'
* upstream-merge: (229 commits) Initialize apic before vcpu main loop Add S390 maintainer information Set default console to virtio on S390x S390 GDB stub Add S390x virtio machine bus Add S390x virtio machine description Add support for S390x system emulation Allocate physical memory in low virtual address space Add KVM support for S390x S/390 CPU fake emulation S/390 fake TCG implementation S/390 host/target build system support Sparc64: handle MMU global bit and nucleus context monitor: fix use of plain integer as NULL pointer, spotted by Sparse Add "static" to please Sparse scsi: fix incorrect ?: use monitor: use qemu_gettimeofday(), not gettimeofday() win32: fix variable use before initialization monitor: rename EVENT_* to QEVENT_* to avoid conflict on mingw32 Sparc64: fix compilation with DEBUG_MMU ... Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu.h5
-rw-r--r--target-i386/kvm.c81
-rw-r--r--target-i386/machine.c6
3 files changed, 92 insertions, 0 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index a638e702b..31412a803 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -711,6 +711,11 @@ typedef struct CPUX86State {
/* For KVM */
uint32_t mp_state;
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;
/* in order to simplify APIC support, we leave this pointer to the
user */
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 552866563..568e2117b 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -226,6 +226,8 @@ int kvm_arch_init_vcpu(CPUState *env)
void kvm_arch_reset_vcpu(CPUState *env)
{
env->interrupt_injected = -1;
+ env->nmi_injected = 0;
+ env->nmi_pending = 0;
}
static int kvm_has_msr_star(CPUState *env)
@@ -700,6 +702,73 @@ static int kvm_get_mp_state(CPUState *env)
return 0;
}
+static int kvm_put_vcpu_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_EVENTS
+ struct kvm_vcpu_events events;
+
+ if (!kvm_has_vcpu_events()) {
+ return 0;
+ }
+
+ events.exception.injected = (env->exception_index >= 0);
+ events.exception.nr = env->exception_index;
+ events.exception.has_error_code = env->has_error_code;
+ events.exception.error_code = env->error_code;
+
+ events.interrupt.injected = (env->interrupt_injected >= 0);
+ events.interrupt.nr = env->interrupt_injected;
+ events.interrupt.soft = env->soft_interrupt;
+
+ events.nmi.injected = env->nmi_injected;
+ events.nmi.pending = env->nmi_pending;
+ events.nmi.masked = !!(env->hflags2 & HF2_NMI_MASK);
+
+ events.sipi_vector = env->sipi_vector;
+
+ return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events);
+#else
+ return 0;
+#endif
+}
+
+static int kvm_get_vcpu_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_EVENTS
+ struct kvm_vcpu_events events;
+ int ret;
+
+ if (!kvm_has_vcpu_events()) {
+ return 0;
+ }
+
+ ret = kvm_vcpu_ioctl(env, KVM_GET_VCPU_EVENTS, &events);
+ if (ret < 0) {
+ return ret;
+ }
+ env->exception_index =
+ events.exception.injected ? events.exception.nr : -1;
+ env->has_error_code = events.exception.has_error_code;
+ env->error_code = events.exception.error_code;
+
+ env->interrupt_injected =
+ events.interrupt.injected ? events.interrupt.nr : -1;
+ env->soft_interrupt = events.interrupt.soft;
+
+ env->nmi_injected = events.nmi.injected;
+ env->nmi_pending = events.nmi.pending;
+ if (events.nmi.masked) {
+ env->hflags2 |= HF2_NMI_MASK;
+ } else {
+ env->hflags2 &= ~HF2_NMI_MASK;
+ }
+
+ env->sipi_vector = events.sipi_vector;
+#endif
+
+ return 0;
+}
+
int kvm_arch_put_registers(CPUState *env)
{
int ret;
@@ -724,6 +793,10 @@ int kvm_arch_put_registers(CPUState *env)
if (ret < 0)
return ret;
+ ret = kvm_put_vcpu_events(env);
+ if (ret < 0)
+ return ret;
+
return 0;
}
@@ -747,6 +820,14 @@ int kvm_arch_get_registers(CPUState *env)
if (ret < 0)
return ret;
+ ret = kvm_get_mp_state(env);
+ if (ret < 0)
+ return ret;
+
+ ret = kvm_get_vcpu_events(env);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 9ac477b35..402eddc7e 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -460,6 +460,11 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
VMSTATE_UINT32_V(mp_state, CPUState, 9),
VMSTATE_UINT64_V(tsc, CPUState, 9),
+ VMSTATE_UINT8_V(soft_interrupt, CPUState, 11),
+ VMSTATE_UINT8_V(nmi_injected, CPUState, 11),
+ VMSTATE_UINT8_V(nmi_pending, CPUState, 11),
+ VMSTATE_UINT8_V(has_error_code, CPUState, 11),
+ VMSTATE_UINT32_V(sipi_vector, CPUState, 11),
/* MCE */
VMSTATE_UINT64_V(mcg_cap, CPUState, 10),
VMSTATE_UINT64_V(mcg_status, CPUState, 10),
@@ -471,6 +476,7 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_UINT64_V(system_time_msr, CPUState, 12),
VMSTATE_UINT64_V(wall_clock_msr, CPUState, 12),
VMSTATE_END_OF_LIST()
+ /* The above list is not sorted /wrt version numbers, watch out! */
}
};