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 <jjherne@us.ibm.com> CC: Dominik Dingel <dingel@linux.vnet.ibm.com> [Dominik Dingel: use gmap_test_and_clear_dirty, locking fixes] Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
a0bf4f149b
commit
15f36ebd34
|
@ -11,6 +11,7 @@
|
|||
* Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Christian Ehrhardt <ehrhardt@de.ibm.com>
|
||||
* Jason J. Herne <jjherne@us.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
@ -179,6 +180,25 @@ int kvm_dev_ioctl_check_extension(long ext)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void kvm_s390_sync_dirty_log(struct kvm *kvm,
|
||||
struct kvm_memory_slot *memslot)
|
||||
{
|
||||
gfn_t cur_gfn, last_gfn;
|
||||
unsigned long address;
|
||||
struct gmap *gmap = kvm->arch.gmap;
|
||||
|
||||
down_read(&gmap->mm->mmap_sem);
|
||||
/* Loop over all guest pages */
|
||||
last_gfn = memslot->base_gfn + memslot->npages;
|
||||
for (cur_gfn = memslot->base_gfn; cur_gfn <= last_gfn; cur_gfn++) {
|
||||
address = gfn_to_hva_memslot(memslot, cur_gfn);
|
||||
|
||||
if (gmap_test_and_clear_dirty(address, gmap))
|
||||
mark_page_dirty(kvm, cur_gfn);
|
||||
}
|
||||
up_read(&gmap->mm->mmap_sem);
|
||||
}
|
||||
|
||||
/* Section: vm related */
|
||||
/*
|
||||
* Get (and clear) the dirty memory log for a memory slot.
|
||||
|
@ -186,7 +206,36 @@ int kvm_dev_ioctl_check_extension(long ext)
|
|||
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
||||
struct kvm_dirty_log *log)
|
||||
{
|
||||
return 0;
|
||||
int r;
|
||||
unsigned long n;
|
||||
struct kvm_memory_slot *memslot;
|
||||
int is_dirty = 0;
|
||||
|
||||
mutex_lock(&kvm->slots_lock);
|
||||
|
||||
r = -EINVAL;
|
||||
if (log->slot >= KVM_USER_MEM_SLOTS)
|
||||
goto out;
|
||||
|
||||
memslot = id_to_memslot(kvm->memslots, log->slot);
|
||||
r = -ENOENT;
|
||||
if (!memslot->dirty_bitmap)
|
||||
goto out;
|
||||
|
||||
kvm_s390_sync_dirty_log(kvm, memslot);
|
||||
r = kvm_get_dirty_log(kvm, log, &is_dirty);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
/* Clear the dirty log */
|
||||
if (is_dirty) {
|
||||
n = kvm_dirty_bitmap_bytes(memslot);
|
||||
memset(memslot->dirty_bitmap, 0, n);
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
mutex_unlock(&kvm->slots_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
|
||||
|
|
|
@ -637,14 +637,12 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
|
|||
*/
|
||||
static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
|
||||
{
|
||||
#ifndef CONFIG_S390
|
||||
unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
|
||||
|
||||
memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes);
|
||||
if (!memslot->dirty_bitmap)
|
||||
return -ENOMEM;
|
||||
|
||||
#endif /* !CONFIG_S390 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue