* [PATCH 1/2] qemu-kvm: x86: Refactor use of interrupt_bitmap
@ 2009-11-03 17:36 Jan Kiszka
2009-11-03 17:42 ` [PATCH 2/2] qemu-kvm: x86: Add support for event states Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2009-11-03 17:36 UTC (permalink / raw)
To: Marcelo Tosatti, Avi Kivity; +Cc: kvm
Drop interrupt_bitmap from the cpustate and solely rely on the integer
interupt_injected. This prepares us for the new injected-interrupt
interface, which will deprecate the bitmap, while preserving
compatibility.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
Note: A corresponding version for upstream is on the way as well.
qemu-kvm-x86.c | 19 +++++++++++++++++--
target-i386/cpu.h | 3 +--
target-i386/kvm.c | 24 +++++++++++++++++-------
target-i386/machine.c | 24 ++----------------------
4 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 9df0d83..e03a4ba 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -946,7 +946,11 @@ void kvm_arch_load_regs(CPUState *env)
fpu.mxcsr = env->mxcsr;
kvm_set_fpu(env, &fpu);
- memcpy(sregs.interrupt_bitmap, env->interrupt_bitmap, sizeof(sregs.interrupt_bitmap));
+ memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap));
+ if (env->interrupt_injected >= 0) {
+ sregs.interrupt_bitmap[env->interrupt_injected / 64] |=
+ (uint64_t)1 << (env->interrupt_injected % 64);
+ }
if ((env->eflags & VM_MASK)) {
set_v8086_seg(&sregs.cs, &env->segs[R_CS]);
@@ -1104,7 +1108,14 @@ void kvm_arch_save_regs(CPUState *env)
kvm_get_sregs(env, &sregs);
- memcpy(env->interrupt_bitmap, sregs.interrupt_bitmap, sizeof(env->interrupt_bitmap));
+ env->interrupt_injected = -1;
+ for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) {
+ if (sregs.interrupt_bitmap[i]) {
+ n = ctz64(sregs.interrupt_bitmap[i]);
+ env->interrupt_injected = i * 64 + n;
+ break;
+ }
+ }
get_seg(&env->segs[R_CS], &sregs.cs);
get_seg(&env->segs[R_DS], &sregs.ds);
@@ -1371,6 +1382,9 @@ int kvm_arch_init_vcpu(CPUState *cenv)
#ifdef KVM_EXIT_TPR_ACCESS
kvm_tpr_vcpu_start(cenv);
#endif
+
+ cenv->interrupt_injected = -1;
+
return 0;
}
@@ -1439,6 +1453,7 @@ void kvm_arch_push_nmi(void *opaque)
void kvm_arch_cpu_reset(CPUState *env)
{
+ env->interrupt_injected = -1;
kvm_arch_load_regs(env);
if (!cpu_is_bsp(env)) {
if (kvm_irqchip_in_kernel()) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4605fd2..a638e70 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -709,8 +709,8 @@ typedef struct CPUX86State {
MTRRVar mtrr_var[8];
/* For KVM */
- uint64_t interrupt_bitmap[256 / 64];
uint32_t mp_state;
+ int32_t interrupt_injected;
/* in order to simplify APIC support, we leave this pointer to the
user */
@@ -727,7 +727,6 @@ typedef struct CPUX86State {
uint16_t fpus_vmstate;
uint16_t fptag_vmstate;
uint16_t fpregs_format_vmstate;
- int32_t pending_irq_vmstate;
} CPUX86State;
CPUX86State *cpu_x86_init(const char *cpu_model);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 24c9903..33f7d65 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -23,6 +23,7 @@
#include "kvm.h"
#include "cpu.h"
#include "gdbstub.h"
+#include "host-utils.h"
#ifdef KVM_UPSTREAM
//#define DEBUG_KVM
@@ -408,9 +409,11 @@ static int kvm_put_sregs(CPUState *env)
{
struct kvm_sregs sregs;
- memcpy(sregs.interrupt_bitmap,
- env->interrupt_bitmap,
- sizeof(sregs.interrupt_bitmap));
+ memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap));
+ if (env->interrupt_injected >= 0) {
+ sregs.interrupt_bitmap[env->interrupt_injected / 64] |=
+ (uint64_t)1 << (env->interrupt_injected % 64);
+ }
if ((env->eflags & VM_MASK)) {
set_v8086_seg(&sregs.cs, &env->segs[R_CS]);
@@ -518,15 +521,22 @@ static int kvm_get_sregs(CPUState *env)
{
struct kvm_sregs sregs;
uint32_t hflags;
- int ret;
+ int bit, i, ret;
ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
if (ret < 0)
return ret;
- memcpy(env->interrupt_bitmap,
- sregs.interrupt_bitmap,
- sizeof(sregs.interrupt_bitmap));
+ /* There can only be one pending IRQ set in the bitmap at a time, so try
+ to find it and save its number instead (-1 for none). */
+ env->interrupt_injected = -1;
+ for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) {
+ if (sregs.interrupt_bitmap[i]) {
+ bit = ctz64(sregs.interrupt_bitmap[i]);
+ env->interrupt_injected = i * 64 + bit;
+ break;
+ }
+ }
get_seg(&env->segs[R_CS], &sregs.cs);
get_seg(&env->segs[R_DS], &sregs.ds);
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 2b88fea..6bd447f 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -2,7 +2,6 @@
#include "hw/boards.h"
#include "hw/pc.h"
#include "hw/isa.h"
-#include "host-utils.h"
#include "exec-all.h"
#include "kvm.h"
@@ -321,7 +320,7 @@ static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
static void cpu_pre_save(void *opaque)
{
CPUState *env = opaque;
- int i, bit;
+ int i;
cpu_synchronize_state(env);
kvm_save_mpstate(env);
@@ -338,17 +337,6 @@ static void cpu_pre_save(void *opaque)
#else
env->fpregs_format_vmstate = 1;
#endif
-
- /* There can only be one pending IRQ set in the bitmap at a time, so try
- to find it and save its number instead (-1 for none). */
- env->pending_irq_vmstate = -1;
- for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) {
- if (env->interrupt_bitmap[i]) {
- bit = ctz64(env->interrupt_bitmap[i]);
- env->pending_irq_vmstate = i * 64 + bit;
- break;
- }
- }
}
static int cpu_pre_load(void *opaque)
@@ -377,14 +365,6 @@ static int cpu_post_load(void *opaque, int version_id)
for (i = 0; i < 4; i++)
hw_breakpoint_insert(env, i);
- if (version_id >= 9) {
- memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
- if (env->pending_irq_vmstate >= 0) {
- env->interrupt_bitmap[env->pending_irq_vmstate / 64] |=
- (uint64_t)1 << (env->pending_irq_vmstate % 64);
- }
- }
-
tlb_flush(env, 1);
kvm_load_mpstate(env);
@@ -469,7 +449,7 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_UINT64_V(mtrr_deftype, CPUState, 8),
VMSTATE_MTRR_VARS(mtrr_var, CPUState, 8, 8),
/* KVM-related states */
- VMSTATE_INT32_V(pending_irq_vmstate, CPUState, 9),
+ VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
VMSTATE_UINT32_V(mp_state, CPUState, 9),
VMSTATE_UINT64_V(tsc, CPUState, 9),
/* MCE */
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] qemu-kvm: x86: Add support for event states
2009-11-03 17:36 [PATCH 1/2] qemu-kvm: x86: Refactor use of interrupt_bitmap Jan Kiszka
@ 2009-11-03 17:42 ` Jan Kiszka
2009-11-05 8:25 ` [PATCH v2 " Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2009-11-03 17:42 UTC (permalink / raw)
To: Marcelo Tosatti, Avi Kivity; +Cc: kvm
This patch extends the qemu-kvm state sync logic with the event substate
from the new VCPU state interface, giving access to yet missing
exception, interrupt and NMI states.
The patch does not switch the rest of qemu-kvm's code to the new
interface as it is expected to be morphed into upstream's version
anyway. Instead, a full conversion will be submitted for upstream.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
qemu-kvm-x86.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
target-i386/cpu.h | 4 ++
target-i386/machine.c | 4 ++
3 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index e03a4ba..b12b103 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -903,6 +903,81 @@ static void get_seg(SegmentCache *lhs, const struct kvm_segment *rhs)
| (rhs->avl * DESC_AVL_MASK);
}
+static void kvm_get_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_STATE
+ struct {
+ struct kvm_vcpu_state header;
+ struct kvm_vcpu_substate substates[1];
+ } request;
+ struct kvm_x86_event_state events;
+ int r;
+
+ request.header.nsubstates = 1;
+ request.header.substates[0].type = KVM_X86_VCPU_STATE_EVENTS;
+ request.header.substates[0].offset = (size_t)&events - (size_t)&request;
+ r = kvm_vcpu_ioctl(env, KVM_GET_VCPU_STATE, &request);
+ if (r == 0) {
+ if (events.exception.injected) {
+ env->exception_index = events.exception.nr;
+ env->error_code = events.exception.error_code;
+ } else {
+ env->exception_index = -1;
+ }
+
+ 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;
+
+ return;
+ }
+#endif
+ env->nmi_injected = 0;
+ env->nmi_pending = 0;
+ env->hflags2 &= ~HF2_NMI_MASK;
+}
+
+static void kvm_set_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_STATE
+ struct {
+ struct kvm_vcpu_state header;
+ struct kvm_vcpu_substate substates[1];
+ } request;
+ struct kvm_x86_event_state events;
+
+ request.header.nsubstates = 1;
+ request.header.substates[0].type = KVM_X86_VCPU_STATE_EVENTS;
+ request.header.substates[0].offset = (size_t)&events - (size_t)&request;
+
+ events.exception.injected = (env->exception_index >= 0);
+ events.exception.nr = env->exception_index;
+ 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;
+
+ kvm_vcpu_ioctl(env, KVM_SET_VCPU_STATE, &request);
+#endif
+}
+
void kvm_arch_load_regs(CPUState *env)
{
struct kvm_regs regs;
@@ -1019,6 +1094,8 @@ void kvm_arch_load_regs(CPUState *env)
rc = kvm_set_msrs(env, msrs, n);
if (rc == -1)
perror("kvm_set_msrs FAILED");
+
+ kvm_set_events(env);
}
void kvm_load_tsc(CPUState *env)
@@ -1215,6 +1292,8 @@ void kvm_arch_save_regs(CPUState *env)
return;
}
}
+
+ kvm_get_events(env);
}
static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function,
@@ -1383,7 +1462,10 @@ int kvm_arch_init_vcpu(CPUState *cenv)
kvm_tpr_vcpu_start(cenv);
#endif
+ cenv->exception_index = -1;
cenv->interrupt_injected = -1;
+ cenv->nmi_injected = 0;
+ cenv->nmi_pending = 0;
return 0;
}
@@ -1453,7 +1535,10 @@ void kvm_arch_push_nmi(void *opaque)
void kvm_arch_cpu_reset(CPUState *env)
{
+ env->exception_index = -1;
env->interrupt_injected = -1;
+ env->nmi_injected = 0;
+ env->nmi_pending = 0;
kvm_arch_load_regs(env);
if (!cpu_is_bsp(env)) {
if (kvm_irqchip_in_kernel()) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index a638e70..863c5a1 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -711,6 +711,10 @@ 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;
+ uint32_t sipi_vector;
/* in order to simplify APIC support, we leave this pointer to the
user */
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 6bd447f..f066e6a 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -452,6 +452,10 @@ 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_UINT32_V(sipi_vector, CPUState, 11),
/* MCE */
VMSTATE_UINT64_V(mcg_cap, CPUState, 10),
VMSTATE_UINT64_V(mcg_status, CPUState, 10),
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v2 2/2] qemu-kvm: x86: Add support for event states
2009-11-03 17:42 ` [PATCH 2/2] qemu-kvm: x86: Add support for event states Jan Kiszka
@ 2009-11-05 8:25 ` Jan Kiszka
2009-11-06 8:44 ` Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2009-11-05 8:25 UTC (permalink / raw)
To: Marcelo Tosatti, Avi Kivity; +Cc: kvm
This patch extends the qemu-kvm state sync logic with the event substate
from the new VCPU state interface, giving access to yet missing
exception, interrupt and NMI states.
The patch does not switch the rest of qemu-kvm's code to the new
interface as it is expected to be morphed into upstream's version
anyway. Instead, a full conversion will be submitted for upstream.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
Changes from v1:
- added support for has_error_code
- properly clear exception_index and interrupt_injected in case the
kernel does not support KVM_GET_VCPU_STATE
qemu-kvm-x86.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
target-i386/cpu.h | 5 +++
target-i386/machine.c | 5 +++
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index e03a4ba..dc3e6cb 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -903,6 +903,82 @@ static void get_seg(SegmentCache *lhs, const struct kvm_segment *rhs)
| (rhs->avl * DESC_AVL_MASK);
}
+static void kvm_get_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_STATE
+ struct {
+ struct kvm_vcpu_state header;
+ struct kvm_vcpu_substate substates[1];
+ } request;
+ struct kvm_x86_event_state events;
+ int r;
+
+ request.header.nsubstates = 1;
+ request.header.substates[0].type = KVM_X86_VCPU_STATE_EVENTS;
+ request.header.substates[0].offset = (size_t)&events - (size_t)&request;
+ r = kvm_vcpu_ioctl(env, KVM_GET_VCPU_STATE, &request);
+ if (r == 0) {
+ 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;
+
+ return;
+ }
+#endif
+ env->exception_index = -1;
+ env->interrupt_injected = -1;
+ env->nmi_injected = 0;
+ env->nmi_pending = 0;
+ env->hflags2 &= ~HF2_NMI_MASK;
+}
+
+static void kvm_set_events(CPUState *env)
+{
+#ifdef KVM_CAP_VCPU_STATE
+ struct {
+ struct kvm_vcpu_state header;
+ struct kvm_vcpu_substate substates[1];
+ } request;
+ struct kvm_x86_event_state events;
+
+ request.header.nsubstates = 1;
+ request.header.substates[0].type = KVM_X86_VCPU_STATE_EVENTS;
+ request.header.substates[0].offset = (size_t)&events - (size_t)&request;
+
+ 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;
+
+ kvm_vcpu_ioctl(env, KVM_SET_VCPU_STATE, &request);
+#endif
+}
+
void kvm_arch_load_regs(CPUState *env)
{
struct kvm_regs regs;
@@ -1019,6 +1095,8 @@ void kvm_arch_load_regs(CPUState *env)
rc = kvm_set_msrs(env, msrs, n);
if (rc == -1)
perror("kvm_set_msrs FAILED");
+
+ kvm_set_events(env);
}
void kvm_load_tsc(CPUState *env)
@@ -1215,6 +1293,8 @@ void kvm_arch_save_regs(CPUState *env)
return;
}
}
+
+ kvm_get_events(env);
}
static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function,
@@ -1383,7 +1463,10 @@ int kvm_arch_init_vcpu(CPUState *cenv)
kvm_tpr_vcpu_start(cenv);
#endif
+ cenv->exception_index = -1;
cenv->interrupt_injected = -1;
+ cenv->nmi_injected = 0;
+ cenv->nmi_pending = 0;
return 0;
}
@@ -1453,7 +1536,10 @@ void kvm_arch_push_nmi(void *opaque)
void kvm_arch_cpu_reset(CPUState *env)
{
+ env->exception_index = -1;
env->interrupt_injected = -1;
+ env->nmi_injected = 0;
+ env->nmi_pending = 0;
kvm_arch_load_regs(env);
if (!cpu_is_bsp(env)) {
if (kvm_irqchip_in_kernel()) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index a638e70..31412a8 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/machine.c b/target-i386/machine.c
index 6bd447f..1eda7c5 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -452,6 +452,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),
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v2 2/2] qemu-kvm: x86: Add support for event states
2009-11-05 8:25 ` [PATCH v2 " Jan Kiszka
@ 2009-11-06 8:44 ` Jan Kiszka
0 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2009-11-06 8:44 UTC (permalink / raw)
To: Marcelo Tosatti, Avi Kivity; +Cc: kvm
[-- Attachment #1: Type: text/plain, Size: 2985 bytes --]
Jan Kiszka wrote:
> This patch extends the qemu-kvm state sync logic with the event substate
> from the new VCPU state interface, giving access to yet missing
> exception, interrupt and NMI states.
>
> The patch does not switch the rest of qemu-kvm's code to the new
> interface as it is expected to be morphed into upstream's version
> anyway. Instead, a full conversion will be submitted for upstream.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
> Changes from v1:
> - added support for has_error_code
> - properly clear exception_index and interrupt_injected in case the
> kernel does not support KVM_GET_VCPU_STATE
>
> qemu-kvm-x86.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
> target-i386/cpu.h | 5 +++
> target-i386/machine.c | 5 +++
> 3 files changed, 96 insertions(+), 0 deletions(-)
>
> diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
> index e03a4ba..dc3e6cb 100644
> --- a/qemu-kvm-x86.c
> +++ b/qemu-kvm-x86.c
> @@ -903,6 +903,82 @@ static void get_seg(SegmentCache *lhs, const struct kvm_segment *rhs)
> | (rhs->avl * DESC_AVL_MASK);
> }
>
> +static void kvm_get_events(CPUState *env)
> +{
> +#ifdef KVM_CAP_VCPU_STATE
> + struct {
> + struct kvm_vcpu_state header;
> + struct kvm_vcpu_substate substates[1];
> + } request;
> + struct kvm_x86_event_state events;
> + int r;
> +
> + request.header.nsubstates = 1;
> + request.header.substates[0].type = KVM_X86_VCPU_STATE_EVENTS;
> + request.header.substates[0].offset = (size_t)&events - (size_t)&request;
> + r = kvm_vcpu_ioctl(env, KVM_GET_VCPU_STATE, &request);
> + if (r == 0) {
> + 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;
> +
> + return;
> + }
> +#endif
> + env->exception_index = -1;
> + env->interrupt_injected = -1;
> + env->nmi_injected = 0;
> + env->nmi_pending = 0;
> + env->hflags2 &= ~HF2_NMI_MASK;
Frankly, I don't recall anymore why I added these 5 lines. This state is
reached on every guest reset and won't change afterwards unless the
kernel actually supports KVM_X86_VCPU_STATE_EVENTS.
This is temporary code, the upstream version will not contain it, but if
you want me to clean this up, just drop me a note.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-11-06 8:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-03 17:36 [PATCH 1/2] qemu-kvm: x86: Refactor use of interrupt_bitmap Jan Kiszka
2009-11-03 17:42 ` [PATCH 2/2] qemu-kvm: x86: Add support for event states Jan Kiszka
2009-11-05 8:25 ` [PATCH v2 " Jan Kiszka
2009-11-06 8:44 ` Jan Kiszka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox