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: [RFC][PATCH] qemu-kvm: x86: Refactor persistent CPU state
Date: Thu, 21 May 2009 22:55:39 +0200 [thread overview]
Message-ID: <4A15BFCB.6050403@web.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 4672 bytes --]
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.
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 399204d..18ba983 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -37,7 +37,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);
@@ -152,13 +153,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 < sizeof(env->interrupt_bitmap)/2; i++) {
+ bit = ffs(((uint16_t *)env->interrupt_bitmap)[i]);
+ if (bit) {
+ pending_irq = i * 16 + bit;
+ 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
@@ -192,9 +201,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]);
@@ -339,6 +348,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;
@@ -347,14 +366,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 reply other threads:[~2009-05-21 20:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-21 20:55 Jan Kiszka [this message]
2009-05-24 12:13 ` [RFC][PATCH] qemu-kvm: x86: Refactor persistent CPU state Avi Kivity
2009-05-25 6:47 ` [PATCH v2] " Jan Kiszka
2009-05-27 9:48 ` 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=4A15BFCB.6050403@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.