aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-07-28 20:52:11 +0300
committerAvi Kivity <avi@redhat.com>2009-07-28 20:52:11 +0300
commit47159e9b25e1d05b5cd591e295e97897c53a9f75 (patch)
tree1563bcfa1c3a76c5b2123f436582a59d5ee39240 /kvm-all.c
parentMerge commit '42bc608b2a144dfa5141dd6ba5d12cb97ac804a7' into upstream-merge (diff)
parentintroduce on_vcpu (diff)
downloadqemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.tar.gz
qemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.tar.bz2
qemu-kvm-47159e9b25e1d05b5cd591e295e97897c53a9f75.zip
Merge commit '452e475196a3f8b6b96d16bbaca727ebc1278a97' into upstream-merge
* commit '452e475196a3f8b6b96d16bbaca727ebc1278a97': (55 commits) introduce on_vcpu qemu-io: reject invalid pattern qemu-io: Rework alloc command qmu-img: fix qemu-img convert to generate a valid image when the source referenced a backing file vmdk: Fix backing file handling use struct initializer for audio.c Add save/restore support to the LSI logic SCSI device model. Handle BH's queued by AIO completions in qemu_aio_flush() Fake dirty loggin when it's not there Use correct input constant Fix warning in kvm-all.c Set PVR in sregs Enable PPC KVM for non-embedded Sparc32: convert Sun4c interrupt controller to qdev Sparc32: convert SBI to qdev Fix CONFIG_PROFILER Sparc32/64: use 64 bit type for memory size qdev: add 64 bit type Sparc64: refactor kernel init Sparc64: refactor CPU init ... Conflicts: kvm-all.c Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'kvm-all.c')
-rw-r--r--kvm-all.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/kvm-all.c b/kvm-all.c
index b4b5a35f4..60c7b2f01 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -154,6 +154,15 @@ static void kvm_reset_vcpu(void *opaque)
}
}
+static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
+{
+ if (env == cpu_single_env) {
+ func(data);
+ return;
+ }
+ abort();
+}
+
int kvm_init_vcpu(CPUState *env)
{
KVMState *s = kvm_state;
@@ -227,7 +236,7 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,
if (mem == NULL) {
fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-"
TARGET_FMT_plx "\n", __func__, phys_addr,
- phys_addr + size - 1);
+ (target_phys_addr_t)(phys_addr + size - 1));
return -EINVAL;
}
@@ -301,6 +310,7 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
KVMDirtyLog d;
KVMSlot *mem;
int ret = 0;
+ int r;
d.dirty_bitmap = NULL;
while (start_addr < end_addr) {
@@ -309,6 +319,11 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
break;
}
+ /* We didn't activate dirty logging? Don't care then. */
+ if(!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) {
+ continue;
+ }
+
size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
if (!d.dirty_bitmap) {
d.dirty_bitmap = qemu_malloc(size);
@@ -320,7 +335,8 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
d.slot = mem->slot;
- if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
+ r = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
+ if (r == -EINVAL) {
dprintf("ioctl failed %d\n", errno);
ret = -1;
break;
@@ -336,6 +352,10 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
if ((bitmap[word] >> bit) & 1) {
cpu_physical_memory_set_dirty(addr);
+ } else if (r < 0) {
+ /* When our KVM implementation doesn't know about dirty logging
+ * we can just assume it's always dirty and be fine. */
+ cpu_physical_memory_set_dirty(addr);
}
}
start_addr = phys_addr;
@@ -898,18 +918,33 @@ int kvm_sw_breakpoints_active(CPUState *env)
}
#ifdef KVM_UPSTREAM
+
+struct kvm_set_guest_debug_data {
+ struct kvm_guest_debug dbg;
+ CPUState *env;
+ int err;
+};
+
+static void kvm_invoke_set_guest_debug(void *data)
+{
+ struct kvm_set_guest_debug_data *dbg_data = data;
+ dbg_data->err = kvm_vcpu_ioctl(dbg_data->env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
+}
+
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
{
- struct kvm_guest_debug dbg;
+ struct kvm_set_guest_debug_data data;
- dbg.control = 0;
+ data.dbg.control = 0;
if (env->singlestep_enabled)
- dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
+ data.dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
- kvm_arch_update_guest_debug(env, &dbg);
- dbg.control |= reinject_trap;
+ kvm_arch_update_guest_debug(env, &data.dbg);
+ data.dbg.control |= reinject_trap;
+ data.env = env;
- return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg);
+ on_vcpu(env, kvm_invoke_set_guest_debug, &data);
+ return data.err;
}
#endif