forked from mirrors/linux
		
	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
					
				
					 2 changed files with 50 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -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 a new issue