From: Jan Kiszka <jan.kiszka@web.de>
To: Avi Kivity <avi@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>, kvm-devel <kvm@vger.kernel.org>
Subject: [PATCH v2] qemu-kvm: x86: Refactor persistent CPU state
Date: Mon, 25 May 2009 08:47:49 +0200 [thread overview]
Message-ID: <4A1A3F15.30809@web.de> (raw)
In-Reply-To: <4A1939CC.8030206@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 6330 bytes --]
Avi Kivity wrote:
> Jan Kiszka wrote:
>> This patch reworks the KVM-related layout and encoding of the CPU state
>> to be saved to disk or migrated. The goal is to define a format, version
>> 9, that is also acceptable for upstream and can later be merged into
>> QEMU. Besides unconditionally writing KVM states, this format compresses
>> interrupt_bitmap into a single number as there can be no more than one
>> pending IRQ at a time.
>>
>>
>> - if (kvm_enabled()) {
>> - for (i = 0; i < sizeof(env->interrupt_bitmap)/8 ; i++) {
>> - qemu_put_be64s(f, &env->interrupt_bitmap[i]);
>> + /* KVM-related states */
>> +
>> + /* 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). */
>> + pending_irq = -1;
>> + for (i = 0; i < sizeof(env->interrupt_bitmap)/2; i++) {
>> + bit = ffs(((uint16_t *)env->interrupt_bitmap)[i]);
>> + if (bit) {
>> + pending_irq = i * 16 + bit;
>>
>
> bit - 1
Fixed.
>
>> + break;
>> }
>>
>
> Why are you using uint64_t? It would be more natural to use ffsll and
> the natural type of the bitmap vector.
Better don't ask how I interpreted the ffs doc.
>
>> + } else {
>> + kvm_load_registers(env);
>> + kvm_load_tsc(env);
>> kvm_load_mpstate(env);
>> }
>> }
>>
>
> Don't you need to load the pending interrupt?
>
For >= v9 this is done in the previous hunk.
------------>
This patch reworks the KVM-related layout and encoding of the CPU state
to be saved to disk or migrated. The goal is to define a format, version
9, that is also acceptable for upstream and can later be merged into
QEMU. Besides unconditionally writing KVM states, this format compresses
interrupt_bitmap into a single number as there can be no more than one
pending IRQ at a time.
Changes in v2:
- fixed and simplified interrupt_bitmap parsing
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
target-i386/cpu.h | 2 +-
target-i386/machine.c | 57 +++++++++++++++++++++++++++++++++++--------------
2 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f054af1..e07b504 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -838,7 +838,7 @@ static inline int cpu_get_time_fast(void)
#define cpu_signal_handler cpu_x86_signal_handler
#define cpu_list x86_cpu_list
-#define CPU_SAVE_VERSION 8
+#define CPU_SAVE_VERSION 9
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _kernel
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 59472d0..67a6e60 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -28,7 +28,8 @@ void cpu_save(QEMUFile *f, void *opaque)
uint16_t fptag, fpus, fpuc, fpregs_format;
uint32_t hflags;
int32_t a20_mask;
- int i;
+ int32_t pending_irq;
+ int i, bit;
if (kvm_enabled()) {
kvm_save_registers(env);
@@ -143,13 +144,21 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_be64s(f, &env->mtrr_var[i].mask);
}
- if (kvm_enabled()) {
- for (i = 0; i < sizeof(env->interrupt_bitmap)/8 ; i++) {
- qemu_put_be64s(f, &env->interrupt_bitmap[i]);
+ /* KVM-related states */
+
+ /* 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). */
+ pending_irq = -1;
+ for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) {
+ bit = ffsll(env->interrupt_bitmap[i]);
+ if (bit) {
+ pending_irq = i * 64 + bit - 1;
+ break;
}
- qemu_put_be64s(f, &env->tsc);
- qemu_put_be32s(f, &env->mp_state);
}
+ qemu_put_sbe32s(f, &pending_irq);
+ qemu_put_be32s(f, &env->mp_state);
+ qemu_put_be64s(f, &env->tsc);
}
#ifdef USE_X86LDOUBLE
@@ -183,9 +192,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
uint32_t hflags;
uint16_t fpus, fpuc, fptag, fpregs_format;
int32_t a20_mask;
+ int32_t pending_irq;
- if (version_id != 3 && version_id != 4 && version_id != 5
- && version_id != 6 && version_id != 7 && version_id != 8)
+ if (version_id < 3 || version_id > CPU_SAVE_VERSION)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_get_betls(f, &env->regs[i]);
@@ -330,6 +339,16 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
}
}
+ if (version_id >= 9) {
+ qemu_get_sbe32s(f, &pending_irq);
+ memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
+ if (pending_irq >= 0) {
+ env->interrupt_bitmap[pending_irq / 64] |= 1 << (pending_irq % 64);
+ }
+ qemu_get_be32s(f, &env->mp_state);
+ qemu_get_be64s(f, &env->tsc);
+ }
+
/* XXX: ensure compatiblity for halted bit ? */
/* XXX: compute redundant hflags bits */
env->hflags = hflags;
@@ -338,14 +357,20 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
/* when in-kernel irqchip is used, env->halted causes deadlock
because no userspace IRQs will ever clear this flag */
env->halted = 0;
- for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
- qemu_get_be64s(f, &env->interrupt_bitmap[i]);
- }
- qemu_get_be64s(f, &env->tsc);
- kvm_load_registers(env);
- kvm_load_tsc(env);
- if (version_id >= 5) {
- qemu_get_be32s(f, &env->mp_state);
+ if (version_id < 9) {
+ for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
+ qemu_get_be64s(f, &env->interrupt_bitmap[i]);
+ }
+ qemu_get_be64s(f, &env->tsc);
+ kvm_load_registers(env);
+ kvm_load_tsc(env);
+ if (version_id >= 5) {
+ qemu_get_be32s(f, &env->mp_state);
+ kvm_load_mpstate(env);
+ }
+ } else {
+ kvm_load_registers(env);
+ kvm_load_tsc(env);
kvm_load_mpstate(env);
}
}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
next prev parent reply other threads:[~2009-05-25 6:47 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-21 20:55 [RFC][PATCH] qemu-kvm: x86: Refactor persistent CPU state Jan Kiszka
2009-05-24 12:13 ` Avi Kivity
2009-05-25 6:47 ` Jan Kiszka [this message]
2009-05-27 9:48 ` [PATCH v2] " Avi Kivity
2009-05-27 10:16 ` [PATCH v3] " Jan Kiszka
2009-05-27 11:03 ` Avi Kivity
2009-05-27 11:39 ` Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A1A3F15.30809@web.de \
--to=jan.kiszka@web.de \
--cc=avi@redhat.com \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.