* [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue
@ 2011-05-02 18:32 Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 1/9] kvm: use kernel-provided para_features instead of statically coming up with new capabilities Marcelo Tosatti
` (9 more replies)
0 siblings, 10 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel, kvm
The following changes since commit cd18f05e248bb916028021634058da06a4657e26:
Don't zero out buffer in sched_getaffinity (2011-05-02 10:00:01 +0300)
are available in the git repository at:
git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
Glauber Costa (3):
kvm: use kernel-provided para_features instead of statically coming up with new capabilities
kvm: add kvmclock to its second bit
kvm: create kvmclock when one of the flags are present
Jan Kiszka (4):
x86: Allow multiple cpu feature matches of lookup_feature
Break up user and system cpu_interrupt implementations
Redirect cpu_interrupt to callback handler
kvm: Install specialized interrupt handler
Michael Tokarev (1):
fix crash in migration, 32-bit userspace on 64-bit host
Paolo Bonzini (1):
kvm: use qemu_free consistently
cpu-all.h | 14 ++++++++-
exec.c | 18 ++++++++---
hw/kvmclock.c | 6 +++-
kvm-all.c | 30 +++++++++++++++++--
target-i386/cpuid.c | 16 ++++++----
target-i386/kvm.c | 80 ++++++++++++++++++++++++++++++++-------------------
6 files changed, 117 insertions(+), 47 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 1/9] kvm: use kernel-provided para_features instead of statically coming up with new capabilities
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 2/9] x86: Allow multiple cpu feature matches of lookup_feature Marcelo Tosatti
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel, kvm, Avi Kivity
From: Glauber Costa <glommer@redhat.com>
Use the features provided by KVM_GET_SUPPORTED_CPUID directly to
mask out features from guest-visible cpuid.
The old get_para_features() mechanism is kept for older kernels that do not implement it.
Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
target-i386/kvm.c | 78 +++++++++++++++++++++++++++++++++-------------------
1 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a13599d..485572f 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -92,6 +92,35 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
return cpuid;
}
+#ifdef CONFIG_KVM_PARA
+struct kvm_para_features {
+ int cap;
+ int feature;
+} para_features[] = {
+ { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+ { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
+ { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
+#ifdef KVM_CAP_ASYNC_PF
+ { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
+#endif
+ { -1, -1 }
+};
+
+static int get_para_features(CPUState *env)
+{
+ int i, features = 0;
+
+ for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+ if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
+ features |= (1 << para_features[i].feature);
+ }
+ }
+
+ return features;
+}
+#endif
+
+
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
uint32_t index, int reg)
{
@@ -99,6 +128,9 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
int i, max;
uint32_t ret = 0;
uint32_t cpuid_1_edx;
+#ifdef CONFIG_KVM_PARA
+ int has_kvm_features = 0;
+#endif
max = 1;
while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
@@ -108,6 +140,11 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
for (i = 0; i < cpuid->nent; ++i) {
if (cpuid->entries[i].function == function &&
cpuid->entries[i].index == index) {
+#ifdef CONFIG_KVM_PARA
+ if (cpuid->entries[i].function == KVM_CPUID_FEATURES) {
+ has_kvm_features = 1;
+ }
+#endif
switch (reg) {
case R_EAX:
ret = cpuid->entries[i].eax;
@@ -140,38 +177,15 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
qemu_free(cpuid);
- return ret;
-}
-
#ifdef CONFIG_KVM_PARA
-struct kvm_para_features {
- int cap;
- int feature;
-} para_features[] = {
- { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
- { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
- { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
-#ifdef KVM_CAP_ASYNC_PF
- { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
-#endif
- { -1, -1 }
-};
-
-static int get_para_features(CPUState *env)
-{
- int i, features = 0;
-
- for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
- if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
- features |= (1 << para_features[i].feature);
- }
+ /* fallback for older kernels */
+ if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
+ ret = get_para_features(env);
}
-#ifdef KVM_CAP_ASYNC_PF
- has_msr_async_pf_en = features & (1 << KVM_FEATURE_ASYNC_PF);
#endif
- return features;
+
+ return ret;
}
-#endif /* CONFIG_KVM_PARA */
typedef struct HWPoisonPage {
ram_addr_t ram_addr;
@@ -397,7 +411,13 @@ int kvm_arch_init_vcpu(CPUState *env)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_FEATURES;
- c->eax = env->cpuid_kvm_features & get_para_features(env);
+ c->eax = env->cpuid_kvm_features & kvm_arch_get_supported_cpuid(env,
+ KVM_CPUID_FEATURES, 0, R_EAX);
+
+#ifdef KVM_CAP_ASYNC_PF
+ has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
+#endif
+
#endif
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/9] x86: Allow multiple cpu feature matches of lookup_feature
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 1/9] kvm: use kernel-provided para_features instead of statically coming up with new capabilities Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 3/9] kvm: add kvmclock to its second bit Marcelo Tosatti
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Jan Kiszka, Marcelo Tosatti, qemu-devel, kvm
From: Jan Kiszka <jan.kiszka@siemens.com>
kvmclock is represented by two feature bits. Therefore, lookup_feature
needs to continue its search even after the first match. Enhance it
accordingly and switch to a bool return type at this chance.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
target-i386/cpuid.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 814d13e..0ac592f 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -182,20 +182,22 @@ static int altcmp(const char *s, const char *e, const char *altstr)
}
/* search featureset for flag *[s..e), if found set corresponding bit in
- * *pval and return success, otherwise return zero
+ * *pval and return true, otherwise return false
*/
-static int lookup_feature(uint32_t *pval, const char *s, const char *e,
- const char **featureset)
+static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
+ const char **featureset)
{
uint32_t mask;
const char **ppc;
+ bool found = false;
- for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc)
+ for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
if (*ppc && !altcmp(s, e, *ppc)) {
*pval |= mask;
- break;
+ found = true;
}
- return (mask ? 1 : 0);
+ }
+ return found;
}
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 3/9] kvm: add kvmclock to its second bit
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 1/9] kvm: use kernel-provided para_features instead of statically coming up with new capabilities Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 2/9] x86: Allow multiple cpu feature matches of lookup_feature Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 4/9] kvm: create kvmclock when one of the flags are present Marcelo Tosatti
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel, kvm, Avi Kivity
From: Glauber Costa <glommer@redhat.com>
We have two bits that can represent kvmclock in cpuid.
They signal the guest which msr set to use. When we tweak flags
involving this value - specially when we use "-", we have to act on both.
Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
target-i386/cpuid.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 0ac592f..e479a4d 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = {
};
static const char *kvm_feature_name[] = {
- "kvmclock", "kvm_nopiodelay", "kvm_mmu", NULL, "kvm_asyncpf", NULL, NULL, NULL,
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 4/9] kvm: create kvmclock when one of the flags are present
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (2 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 3/9] kvm: add kvmclock to its second bit Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 5/9] Break up user and system cpu_interrupt implementations Marcelo Tosatti
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel, kvm, Avi Kivity
From: Glauber Costa <glommer@redhat.com>
kvmclock presence can be signalled by two different flags. So for
device creation, we have to test for both.
Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
hw/kvmclock.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index b6ceddf..004c4ad 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -103,7 +103,11 @@ static SysBusDeviceInfo kvmclock_info = {
void kvmclock_create(void)
{
if (kvm_enabled() &&
- first_cpu->cpuid_kvm_features & (1ULL << KVM_FEATURE_CLOCKSOURCE)) {
+ first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE)
+#ifdef KVM_FEATURE_CLOCKSOURCE2
+ || (1ULL << KVM_FEATURE_CLOCKSOURCE2)
+#endif
+ )) {
sysbus_create_simple("kvmclock", -1, NULL);
}
}
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 5/9] Break up user and system cpu_interrupt implementations
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (3 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 4/9] kvm: create kvmclock when one of the flags are present Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 6/9] Redirect cpu_interrupt to callback handler Marcelo Tosatti
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Jan Kiszka, Riku Voipio, qemu-devel, kvm, Marcelo Tosatti
From: Jan Kiszka <jan.kiszka@siemens.com>
Both have only two lines in common, and we will convert the system
service into a callback which is of no use for user mode operation.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
exec.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/exec.c b/exec.c
index c3dc68a..d6d8a89 100644
--- a/exec.c
+++ b/exec.c
@@ -1629,6 +1629,7 @@ static void cpu_unlink_tb(CPUState *env)
spin_unlock(&interrupt_lock);
}
+#ifndef CONFIG_USER_ONLY
/* mask must never be zero, except for A20 change call */
void cpu_interrupt(CPUState *env, int mask)
{
@@ -1637,7 +1638,6 @@ void cpu_interrupt(CPUState *env, int mask)
old_mask = env->interrupt_request;
env->interrupt_request |= mask;
-#ifndef CONFIG_USER_ONLY
/*
* If called from iothread context, wake the target cpu in
* case its halted.
@@ -1646,21 +1646,27 @@ void cpu_interrupt(CPUState *env, int mask)
qemu_cpu_kick(env);
return;
}
-#endif
if (use_icount) {
env->icount_decr.u16.high = 0xffff;
-#ifndef CONFIG_USER_ONLY
if (!can_do_io(env)
&& (mask & ~old_mask) != 0) {
cpu_abort(env, "Raised interrupt while not in I/O function");
}
-#endif
} else {
cpu_unlink_tb(env);
}
}
+#else /* CONFIG_USER_ONLY */
+
+void cpu_interrupt(CPUState *env, int mask)
+{
+ env->interrupt_request |= mask;
+ cpu_unlink_tb(env);
+}
+#endif /* CONFIG_USER_ONLY */
+
void cpu_reset_interrupt(CPUState *env, int mask)
{
env->interrupt_request &= ~mask;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 6/9] Redirect cpu_interrupt to callback handler
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (4 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 5/9] Break up user and system cpu_interrupt implementations Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 7/9] kvm: Install specialized interrupt handler Marcelo Tosatti
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Jan Kiszka, Marcelo Tosatti, qemu-devel, kvm
From: Jan Kiszka <jan.kiszka@siemens.com>
This allows to override the interrupt handling of QEMU in system mode.
KVM will make use of it to set a specialized handler.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
cpu-all.h | 14 +++++++++++++-
exec.c | 4 +++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/cpu-all.h b/cpu-all.h
index 0bae6df..88126ea 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -799,7 +799,19 @@ extern CPUState *cpu_single_env;
#define CPU_INTERRUPT_SIPI 0x800 /* SIPI pending. */
#define CPU_INTERRUPT_MCE 0x1000 /* (x86 only) MCE pending. */
-void cpu_interrupt(CPUState *s, int mask);
+#ifndef CONFIG_USER_ONLY
+typedef void (*CPUInterruptHandler)(CPUState *, int);
+
+extern CPUInterruptHandler cpu_interrupt_handler;
+
+static inline void cpu_interrupt(CPUState *s, int mask)
+{
+ cpu_interrupt_handler(s, mask);
+}
+#else /* USER_ONLY */
+void cpu_interrupt(CPUState *env, int mask);
+#endif /* USER_ONLY */
+
void cpu_reset_interrupt(CPUState *env, int mask);
void cpu_exit(CPUState *s);
diff --git a/exec.c b/exec.c
index d6d8a89..a718d74 100644
--- a/exec.c
+++ b/exec.c
@@ -1631,7 +1631,7 @@ static void cpu_unlink_tb(CPUState *env)
#ifndef CONFIG_USER_ONLY
/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
+static void tcg_handle_interrupt(CPUState *env, int mask)
{
int old_mask;
@@ -1658,6 +1658,8 @@ void cpu_interrupt(CPUState *env, int mask)
}
}
+CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
+
#else /* CONFIG_USER_ONLY */
void cpu_interrupt(CPUState *env, int mask)
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 7/9] kvm: Install specialized interrupt handler
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (5 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 6/9] Redirect cpu_interrupt to callback handler Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 8/9] fix crash in migration, 32-bit userspace on 64-bit host Marcelo Tosatti
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Jan Kiszka, Marcelo Tosatti, qemu-devel, kvm
From: Jan Kiszka <jan.kiszka@siemens.com>
KVM only requires to set the raised IRQ in CPUState and to kick the
receiving vcpu if it is remote. Installing a specialized handler allows
potential future changes to the TCG code path without risking KVM side
effects.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
kvm-all.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index 1d7e8ea..fd1fbfe 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -651,6 +651,15 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = {
.log_stop = kvm_log_stop,
};
+static void kvm_handle_interrupt(CPUState *env, int mask)
+{
+ env->interrupt_request |= mask;
+
+ if (!qemu_cpu_is_self(env)) {
+ qemu_cpu_kick(env);
+ }
+}
+
int kvm_init(void)
{
static const char upgrade_note[] =
@@ -759,6 +768,8 @@ int kvm_init(void)
s->many_ioeventfds = kvm_check_many_ioeventfds();
+ cpu_interrupt_handler = kvm_handle_interrupt;
+
return 0;
err:
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 8/9] fix crash in migration, 32-bit userspace on 64-bit host
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (6 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 7/9] kvm: Install specialized interrupt handler Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 9/9] kvm: use qemu_free consistently Marcelo Tosatti
2011-05-02 18:54 ` [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Anthony Liguori
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori
Cc: Avi Kivity, Michael Tokarev, qemu-devel, kvm, Bruce Rogers
From: Michael Tokarev <mjt@tls.msk.ru>
This change fixes a long-standing immediate crash (memory corruption
and abort in glibc malloc code) in migration on 32bits.
The bug is present since this commit:
commit 692d9aca97b865b0f7903565274a52606910f129
Author: Bruce Rogers <brogers@novell.com>
Date: Wed Sep 23 16:13:18 2009 -0600
qemu-kvm: allocate correct size for dirty bitmap
The dirty bitmap copied out to userspace is stored in a long array,
and gets copied out to userspace accordingly. This patch accounts
for that correctly. Currently I'm seeing kvm crashing due to writing
beyond the end of the alloc'd dirty bitmap memory, because the buffer
has the wrong size.
Signed-off-by: Bruce Rogers
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
- buf = qemu_malloc((slots[i].len / 4096 + 7) / 8 + 2);
+ buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
BITMAP_SIZE is now open-coded in that function, like this:
size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;
The problem is that HOST_LONG_BITS in 32bit userspace is 32
but it's 64 in 64bit kernel. So userspace aligns this to
32, and kernel to 64, but since no length is passed from
userspace to kernel on ioctl, kernel uses its size calculation
and copies 4 extra bytes to userspace, corrupting memory.
Here's how it looks like during migrate execution:
our=20, kern=24
our=4, kern=8
...
our=4, kern=8
our=4064, kern=4064
our=512, kern=512
our=4, kern=8
our=20, kern=24
our=4, kern=8
...
our=4, kern=8
our=4064, kern=4064
*** glibc detected *** ./x86_64-softmmu/qemu-system-x86_64: realloc(): invalid next size: 0x08f20528 ***
(our is userspace size above, kern is the size as calculated
by the kernel).
Fix this by always aligning to 64 in a hope that no platform will
have sizeof(long)>8 any time soon, and add a comment describing it
all. It's a small price to pay for bad kernel design.
Alternatively it's possible to fix that in the kernel by using
different size calculation depending on the current process.
But this becomes quite ugly.
Special thanks goes to Stefan Hajnoczi for spotting the fundamental
cause of the issue, and to Alexander Graf for his support in #qemu.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
CC: Bruce Rogers <brogers@novell.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
kvm-all.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index fd1fbfe..8b85029 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -373,7 +373,20 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
break;
}
- size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;
+ /* XXX bad kernel interface alert
+ * For dirty bitmap, kernel allocates array of size aligned to
+ * bits-per-long. But for case when the kernel is 64bits and
+ * the userspace is 32bits, userspace can't align to the same
+ * bits-per-long, since sizeof(long) is different between kernel
+ * and user space. This way, userspace will provide buffer which
+ * may be 4 bytes less than the kernel will use, resulting in
+ * userspace memory corruption (which is not detectable by valgrind
+ * too, in most cases).
+ * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
+ * a hope that sizeof(long) wont become >8 any time soon.
+ */
+ size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
+ /*HOST_LONG_BITS*/ 64) / 8;
if (!d.dirty_bitmap) {
d.dirty_bitmap = qemu_malloc(size);
} else if (size > allocated_size) {
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 9/9] kvm: use qemu_free consistently
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (7 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 8/9] fix crash in migration, 32-bit userspace on 64-bit host Marcelo Tosatti
@ 2011-05-02 18:32 ` Marcelo Tosatti
2011-05-02 18:54 ` [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Anthony Liguori
9 siblings, 0 replies; 13+ messages in thread
From: Marcelo Tosatti @ 2011-05-02 18:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Paolo Bonzini, Marcelo Tosatti, qemu-devel, kvm
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
kvm-all.c | 4 ++--
target-i386/kvm.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index 8b85029..d92c20e 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1191,7 +1191,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
bp->use_count = 1;
err = kvm_arch_insert_sw_breakpoint(current_env, bp);
if (err) {
- free(bp);
+ qemu_free(bp);
return err;
}
@@ -1315,7 +1315,7 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
sigmask->len = 8;
memcpy(sigmask->sigset, sigset, sizeof(*sigset));
r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask);
- free(sigmask);
+ qemu_free(sigmask);
return r;
}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 485572f..faedc6c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -572,7 +572,7 @@ static int kvm_get_supported_msrs(KVMState *s)
}
}
- free(kvm_msr_list);
+ qemu_free(kvm_msr_list);
}
return ret;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
` (8 preceding siblings ...)
2011-05-02 18:32 ` [Qemu-devel] [PATCH 9/9] kvm: use qemu_free consistently Marcelo Tosatti
@ 2011-05-02 18:54 ` Anthony Liguori
9 siblings, 0 replies; 13+ messages in thread
From: Anthony Liguori @ 2011-05-02 18:54 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: qemu-devel, kvm
On 05/02/2011 01:32 PM, Marcelo Tosatti wrote:
> The following changes since commit cd18f05e248bb916028021634058da06a4657e26:
>
> Don't zero out buffer in sched_getaffinity (2011-05-02 10:00:01 +0300)
Applied. Thanks.
Regards,
Anthony Liguori
>
> are available in the git repository at:
> git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
>
> Glauber Costa (3):
> kvm: use kernel-provided para_features instead of statically coming up with new capabilities
> kvm: add kvmclock to its second bit
> kvm: create kvmclock when one of the flags are present
>
> Jan Kiszka (4):
> x86: Allow multiple cpu feature matches of lookup_feature
> Break up user and system cpu_interrupt implementations
> Redirect cpu_interrupt to callback handler
> kvm: Install specialized interrupt handler
>
> Michael Tokarev (1):
> fix crash in migration, 32-bit userspace on 64-bit host
>
> Paolo Bonzini (1):
> kvm: use qemu_free consistently
>
> cpu-all.h | 14 ++++++++-
> exec.c | 18 ++++++++---
> hw/kvmclock.c | 6 +++-
> kvm-all.c | 30 +++++++++++++++++--
> target-i386/cpuid.c | 16 ++++++----
> target-i386/kvm.c | 80 ++++++++++++++++++++++++++++++++-------------------
> 6 files changed, 117 insertions(+), 47 deletions(-)
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue
@ 2012-09-11 21:26 Marcelo Tosatti
2012-09-17 18:20 ` Anthony Liguori
0 siblings, 1 reply; 13+ messages in thread
From: Marcelo Tosatti @ 2012-09-11 21:26 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Marcelo Tosatti, qemu-devel, kvm
The following changes since commit e0a1e32dbc41e6b2aabb436a9417dfd32177a3dc:
Merge branch 'usb.64' of git://git.kraxel.org/qemu (2012-09-11 18:06:56 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
Jan Kiszka (7):
memory: Flush coalesced MMIO on selected region access
memory: Use transaction_begin/commit also for single-step operations
memory: Fold memory_region_update_topology into memory_region_transaction_commit
memory: Flush coalesced MMIO on mapping and state changes
VGA: Flush coalesced MMIO on related MMIO/PIO accesses
kvm: Stop flushing coalesced MMIO on vmexit
kvm: Rename irqchip_inject_ioctl to irq_set_ioctl
Peter Maydell (2):
update-linux-headers.sh: Don't hard code list of architectures
kvm-all.c: Move init of irqchip_inject_ioctl out of kvm_irqchip_create()
hw/cirrus_vga.c | 7 +++
hw/qxl.c | 1 +
hw/vga-isa-mm.c | 1 +
hw/vga.c | 5 ++
hw/vmware_vga.c | 1 +
kvm-all.c | 17 +++---
memory.c | 104 +++++++++++++++++++++++----------------
memory.h | 26 ++++++++++
scripts/update-linux-headers.sh | 16 ++++++-
9 files changed, 125 insertions(+), 53 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue
2012-09-11 21:26 Marcelo Tosatti
@ 2012-09-17 18:20 ` Anthony Liguori
0 siblings, 0 replies; 13+ messages in thread
From: Anthony Liguori @ 2012-09-17 18:20 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: qemu-devel, kvm
Marcelo Tosatti <mtosatti@redhat.com> writes:
> The following changes since commit e0a1e32dbc41e6b2aabb436a9417dfd32177a3dc:
>
> Merge branch 'usb.64' of git://git.kraxel.org/qemu (2012-09-11 18:06:56 +0200)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
>
Pulled. Thanks.
Regards,
Anthony Liguori
> Jan Kiszka (7):
> memory: Flush coalesced MMIO on selected region access
> memory: Use transaction_begin/commit also for single-step operations
> memory: Fold memory_region_update_topology into memory_region_transaction_commit
> memory: Flush coalesced MMIO on mapping and state changes
> VGA: Flush coalesced MMIO on related MMIO/PIO accesses
> kvm: Stop flushing coalesced MMIO on vmexit
> kvm: Rename irqchip_inject_ioctl to irq_set_ioctl
>
> Peter Maydell (2):
> update-linux-headers.sh: Don't hard code list of architectures
> kvm-all.c: Move init of irqchip_inject_ioctl out of kvm_irqchip_create()
>
> hw/cirrus_vga.c | 7 +++
> hw/qxl.c | 1 +
> hw/vga-isa-mm.c | 1 +
> hw/vga.c | 5 ++
> hw/vmware_vga.c | 1 +
> kvm-all.c | 17 +++---
> memory.c | 104 +++++++++++++++++++++++----------------
> memory.h | 26 ++++++++++
> scripts/update-linux-headers.sh | 16 ++++++-
> 9 files changed, 125 insertions(+), 53 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-09-17 18:21 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-02 18:32 [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 1/9] kvm: use kernel-provided para_features instead of statically coming up with new capabilities Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 2/9] x86: Allow multiple cpu feature matches of lookup_feature Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 3/9] kvm: add kvmclock to its second bit Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 4/9] kvm: create kvmclock when one of the flags are present Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 5/9] Break up user and system cpu_interrupt implementations Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 6/9] Redirect cpu_interrupt to callback handler Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 7/9] kvm: Install specialized interrupt handler Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 8/9] fix crash in migration, 32-bit userspace on 64-bit host Marcelo Tosatti
2011-05-02 18:32 ` [Qemu-devel] [PATCH 9/9] kvm: use qemu_free consistently Marcelo Tosatti
2011-05-02 18:54 ` [Qemu-devel] [PATCH 0/9] [PULL] qemu-kvm.git uq/master queue Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2012-09-11 21:26 Marcelo Tosatti
2012-09-17 18:20 ` Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).