diff options
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 51 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 2 |
2 files changed, 50 insertions, 3 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index b767ec97368a..346a3478dd00 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 11 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 12 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
13 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | 13 | * Christian Ehrhardt <ehrhardt@de.ibm.com> |
14 | * Jason J. Herne <jjherne@us.ibm.com> | ||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
@@ -179,6 +180,25 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
179 | return r; | 180 | return r; |
180 | } | 181 | } |
181 | 182 | ||
183 | static void kvm_s390_sync_dirty_log(struct kvm *kvm, | ||
184 | struct kvm_memory_slot *memslot) | ||
185 | { | ||
186 | gfn_t cur_gfn, last_gfn; | ||
187 | unsigned long address; | ||
188 | struct gmap *gmap = kvm->arch.gmap; | ||
189 | |||
190 | down_read(&gmap->mm->mmap_sem); | ||
191 | /* Loop over all guest pages */ | ||
192 | last_gfn = memslot->base_gfn + memslot->npages; | ||
193 | for (cur_gfn = memslot->base_gfn; cur_gfn <= last_gfn; cur_gfn++) { | ||
194 | address = gfn_to_hva_memslot(memslot, cur_gfn); | ||
195 | |||
196 | if (gmap_test_and_clear_dirty(address, gmap)) | ||
197 | mark_page_dirty(kvm, cur_gfn); | ||
198 | } | ||
199 | up_read(&gmap->mm->mmap_sem); | ||
200 | } | ||
201 | |||
182 | /* Section: vm related */ | 202 | /* Section: vm related */ |
183 | /* | 203 | /* |
184 | * Get (and clear) the dirty memory log for a memory slot. | 204 | * Get (and clear) the dirty memory log for a memory slot. |
@@ -186,7 +206,36 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
186 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | 206 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, |
187 | struct kvm_dirty_log *log) | 207 | struct kvm_dirty_log *log) |
188 | { | 208 | { |
189 | return 0; | 209 | int r; |
210 | unsigned long n; | ||
211 | struct kvm_memory_slot *memslot; | ||
212 | int is_dirty = 0; | ||
213 | |||
214 | mutex_lock(&kvm->slots_lock); | ||
215 | |||
216 | r = -EINVAL; | ||
217 | if (log->slot >= KVM_USER_MEM_SLOTS) | ||
218 | goto out; | ||
219 | |||
220 | memslot = id_to_memslot(kvm->memslots, log->slot); | ||
221 | r = -ENOENT; | ||
222 | if (!memslot->dirty_bitmap) | ||
223 | goto out; | ||
224 | |||
225 | kvm_s390_sync_dirty_log(kvm, memslot); | ||
226 | r = kvm_get_dirty_log(kvm, log, &is_dirty); | ||
227 | if (r) | ||
228 | goto out; | ||
229 | |||
230 | /* Clear the dirty log */ | ||
231 | if (is_dirty) { | ||
232 | n = kvm_dirty_bitmap_bytes(memslot); | ||
233 | memset(memslot->dirty_bitmap, 0, n); | ||
234 | } | ||
235 | r = 0; | ||
236 | out: | ||
237 | mutex_unlock(&kvm->slots_lock); | ||
238 | return r; | ||
190 | } | 239 | } |
191 | 240 | ||
192 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | 241 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 56baae8c2f56..7facdb1f1374 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -637,14 +637,12 @@ static int kvm_vm_release(struct inode *inode, struct file *filp) | |||
637 | */ | 637 | */ |
638 | static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) | 638 | static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) |
639 | { | 639 | { |
640 | #ifndef CONFIG_S390 | ||
641 | unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); | 640 | unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); |
642 | 641 | ||
643 | memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes); | 642 | memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes); |
644 | if (!memslot->dirty_bitmap) | 643 | if (!memslot->dirty_bitmap) |
645 | return -ENOMEM; | 644 | return -ENOMEM; |
646 | 645 | ||
647 | #endif /* !CONFIG_S390 */ | ||
648 | return 0; | 646 | return 0; |
649 | } | 647 | } |
650 | 648 | ||