Skip to content

Commit 15f36eb

Browse files
Jason J. Herneborntraeger
authored andcommitted
KVM: s390: Add proper dirty bitmap support to S390 kvm.
Replace the kvm_s390_sync_dirty_log() stub with code to construct the KVM dirty_bitmap from S390 memory change bits. Also add code to properly clear the dirty_bitmap size when clearing the bitmap. Signed-off-by: Jason J. Herne <[email protected]> CC: Dominik Dingel <[email protected]> [Dominik Dingel: use gmap_test_and_clear_dirty, locking fixes] Signed-off-by: Christian Borntraeger <[email protected]>
1 parent a0bf4f1 commit 15f36eb

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

arch/s390/kvm/kvm-s390.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* Christian Borntraeger <[email protected]>
1212
* Heiko Carstens <[email protected]>
1313
* Christian Ehrhardt <[email protected]>
14+
* Jason J. Herne <[email protected]>
1415
*/
1516

1617
#include <linux/compiler.h>
@@ -179,14 +180,62 @@ int kvm_dev_ioctl_check_extension(long ext)
179180
return r;
180181
}
181182

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+
182202
/* Section: vm related */
183203
/*
184204
* Get (and clear) the dirty memory log for a memory slot.
185205
*/
186206
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
187207
struct kvm_dirty_log *log)
188208
{
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;
190239
}
191240

192241
static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)

virt/kvm/kvm_main.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,14 +637,12 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
637637
*/
638638
static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
639639
{
640-
#ifndef CONFIG_S390
641640
unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
642641

643642
memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes);
644643
if (!memslot->dirty_bitmap)
645644
return -ENOMEM;
646645

647-
#endif /* !CONFIG_S390 */
648646
return 0;
649647
}
650648

0 commit comments

Comments
 (0)